summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-pci7
-rw-r--r--Documentation/IPMI.txt57
-rw-r--r--Documentation/arm/stm32/overview.txt3
-rw-r--r--Documentation/arm/stm32/stm32f746-overview.txt34
-rw-r--r--Documentation/devicetree/bindings/arm/amlogic,scpi.txt20
-rw-r--r--Documentation/devicetree/bindings/arm/amlogic.txt19
-rw-r--r--Documentation/devicetree/bindings/arm/arm,scpi.txt25
-rw-r--r--Documentation/devicetree/bindings/arm/arm-boards3
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt16
-rw-r--r--Documentation/devicetree/bindings/arm/bcm/brcm,ns2.txt (renamed from Documentation/devicetree/bindings/arm/bcm/ns2.txt)0
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.txt34
-rw-r--r--Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt4
-rw-r--r--Documentation/devicetree/bindings/arm/juno,scpi.txt26
-rw-r--r--Documentation/devicetree/bindings/arm/keystone/ti,sci.txt81
-rw-r--r--Documentation/devicetree/bindings/arm/omap/omap.txt9
-rw-r--r--Documentation/devicetree/bindings/arm/oxnas.txt5
-rw-r--r--Documentation/devicetree/bindings/arm/qcom.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/rockchip.txt16
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt5
-rw-r--r--Documentation/devicetree/bindings/arm/shmobile.txt36
-rw-r--r--Documentation/devicetree/bindings/arm/sunxi.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/swir.txt12
-rw-r--r--Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt2
-rw-r--r--Documentation/devicetree/bindings/ata/ahci-st.txt15
-rw-r--r--Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt132
-rw-r--r--Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt20
-rw-r--r--Documentation/devicetree/bindings/clock/imx31-clock.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/qoriq-clock.txt3
-rw-r--r--Documentation/devicetree/bindings/dma/nbpfaxi.txt8
-rw-r--r--Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt12
-rw-r--r--Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt1
-rw-r--r--Documentation/devicetree/bindings/dma/snps-dma.txt2
-rw-r--r--Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt108
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.txt2
-rw-r--r--Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt16
-rw-r--r--Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt23
-rw-r--r--Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt39
-rw-r--r--Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt19
-rw-r--r--Documentation/devicetree/bindings/gpio/mrvl-gpio.txt6
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt20
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-pxa.txt1
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-rcar.txt32
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt17
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt2
-rw-r--r--Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt2
-rw-r--r--Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt52
-rw-r--r--Documentation/devicetree/bindings/media/renesas,fcp.txt8
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt20
-rw-r--r--Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt1
-rw-r--r--Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt43
-rw-r--r--Documentation/devicetree/bindings/pci/layerscape-pci.txt1
-rw-r--r--Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt110
-rw-r--r--Documentation/devicetree/bindings/pci/pci.txt6
-rw-r--r--Documentation/devicetree/bindings/pci/qcom,pcie.txt14
-rw-r--r--Documentation/devicetree/bindings/pci/rcar-pci.txt1
-rw-r--r--Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt3
-rw-r--r--Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt8
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt2
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-hibvt.txt21
-rw-r--r--Documentation/devicetree/bindings/reset/oxnas,reset.txt44
-rw-r--r--Documentation/devicetree/bindings/reset/st,sti-powerdown.txt12
-rw-r--r--Documentation/devicetree/bindings/reset/st,sti-softreset.txt8
-rw-r--r--Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt2
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/scpsys.txt13
-rw-r--r--Documentation/devicetree/bindings/sram/sram.txt2
-rw-r--r--Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt17
-rw-r--r--Documentation/devicetree/bindings/thermal/st-thermal.txt28
-rw-r--r--Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt17
-rw-r--r--Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt (renamed from Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt)6
-rw-r--r--Documentation/devicetree/bindings/usb/atmel-usb.txt10
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt15
-rw-r--r--Documentation/dmaengine/client.txt16
-rw-r--r--Documentation/dmaengine/dmatest.txt10
-rw-r--r--Documentation/dmaengine/provider.txt2
-rw-r--r--Documentation/dmaengine/pxa_dma.txt2
-rw-r--r--Documentation/filesystems/sysfs-pci.txt2
-rw-r--r--Documentation/filesystems/xfs.txt12
-rw-r--r--Documentation/i2c/busses/i2c-mlxcpld47
-rw-r--r--Documentation/i2c/smbus-protocol12
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt1
-rw-r--r--Documentation/trace/events.txt9
-rw-r--r--Documentation/trace/ftrace.txt15
-rw-r--r--MAINTAINERS50
-rw-r--r--arch/arc/Kconfig13
-rw-r--r--arch/arc/boot/dts/abilis_tb10x.dtsi1
-rw-r--r--arch/arc/boot/dts/axs101.dts2
-rw-r--r--arch/arc/boot/dts/axs103_idu.dts2
-rw-r--r--arch/arc/boot/dts/haps_hs.dts (renamed from arch/arc/boot/dts/zebu_hs.dts)0
-rw-r--r--arch/arc/boot/dts/haps_hs_idu.dts (renamed from arch/arc/boot/dts/zebu_hs_idu.dts)0
-rw-r--r--arch/arc/configs/axs101_defconfig4
-rw-r--r--arch/arc/configs/axs103_smp_defconfig4
-rw-r--r--arch/arc/configs/haps_hs_defconfig (renamed from arch/arc/configs/zebu_hs_defconfig)2
-rw-r--r--arch/arc/configs/haps_hs_smp_defconfig (renamed from arch/arc/configs/zebu_hs_smp_defconfig)2
-rw-r--r--arch/arc/configs/nsimosci_hs_smp_defconfig2
-rw-r--r--arch/arc/configs/vdk_hs38_smp_defconfig2
-rw-r--r--arch/arc/include/asm/arcregs.h94
-rw-r--r--arch/arc/kernel/Makefile2
-rw-r--r--arch/arc/kernel/mcip.c2
-rw-r--r--arch/arc/kernel/setup.c17
-rw-r--r--arch/arc/plat-axs10x/axs10x.c2
-rw-r--r--arch/arc/plat-eznps/include/plat/ctop.h2
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/Makefile6
-rw-r--r--arch/arm/boot/dts/Makefile50
-rw-r--r--arch/arm/boot/dts/am335x-baltos-ir2110.dts10
-rw-r--r--arch/arm/boot/dts/am335x-baltos-ir3220.dts2
-rw-r--r--arch/arm/boot/dts/am335x-baltos-ir5221.dts4
-rw-r--r--arch/arm/boot/dts/am335x-baltos.dtsi9
-rw-r--r--arch/arm/boot/dts/am335x-bone-common.dtsi22
-rw-r--r--arch/arm/boot/dts/am335x-boneblack.dts11
-rw-r--r--arch/arm/boot/dts/am335x-evm.dts5
-rw-r--r--arch/arm/boot/dts/am335x-evmsk.dts5
-rw-r--r--arch/arm/boot/dts/am335x-icev2.dts47
-rw-r--r--arch/arm/boot/dts/am33xx.dtsi6
-rw-r--r--arch/arm/boot/dts/am3517.dtsi1
-rw-r--r--arch/arm/boot/dts/am4372.dtsi3
-rw-r--r--arch/arm/boot/dts/am437x-idk-evm.dts101
-rw-r--r--arch/arm/boot/dts/am571x-idk.dts81
-rw-r--r--arch/arm/boot/dts/am572x-idk.dts4
-rw-r--r--arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi1
-rw-r--r--arch/arm/boot/dts/am57xx-idk-common.dtsi75
-rw-r--r--arch/arm/boot/dts/armada-370-db.dts63
-rw-r--r--arch/arm/boot/dts/armada-370-dlink-dns327l.dts30
-rw-r--r--arch/arm/boot/dts/armada-370-mirabox.dts57
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn102.dts55
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn104.dts63
-rw-r--r--arch/arm/boot/dts/armada-370-rd.dts57
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts27
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi45
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi44
-rw-r--r--arch/arm/boot/dts/armada-370-synology-ds213j.dts18
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi39
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi136
-rw-r--r--arch/arm/boot/dts/armada-375-db.dts271
-rw-r--r--arch/arm/boot/dts/armada-375.dtsi72
-rw-r--r--arch/arm/boot/dts/armada-385-turris-omnia.dts340
-rw-r--r--arch/arm/boot/dts/armada-38x.dtsi2
-rw-r--r--arch/arm/boot/dts/armada-39x.dtsi2
-rw-r--r--arch/arm/boot/dts/armada-xp-axpwifiap.dts68
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts104
-rw-r--r--arch/arm/boot/dts/armada-xp-gp.dts80
-rw-r--r--arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts53
-rw-r--r--arch/arm/boot/dts/armada-xp-linksys-mamba.dts52
-rw-r--r--arch/arm/boot/dts/armada-xp-matrix.dts20
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78230.dtsi12
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78260.dtsi20
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78460.dtsi22
-rw-r--r--arch/arm/boot/dts/armada-xp-netgear-rn2120.dts74
-rw-r--r--arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts58
-rw-r--r--arch/arm/boot/dts/armada-xp-synology-ds414.dts75
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi94
-rw-r--r--arch/arm/boot/dts/artpec6-devboard.dts4
-rw-r--r--arch/arm/boot/dts/artpec6.dtsi29
-rw-r--r--arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi4
-rw-r--r--arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts4
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9260ek.dts4
-rw-r--r--arch/arm/boot/dts/at91sam9261.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9rl.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi4
-rw-r--r--arch/arm/boot/dts/bcm-cygnus.dtsi21
-rw-r--r--arch/arm/boot/dts/bcm-nsp.dtsi41
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-a-plus.dts67
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-a.dts69
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b-plus.dts68
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts68
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b.dts69
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-zero.dts67
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi.dtsi15
-rw-r--r--arch/arm/boot/dts/bcm2835.dtsi6
-rw-r--r--arch/arm/boot/dts/bcm2836-rpi-2-b.dts2
-rw-r--r--arch/arm/boot/dts/bcm2836.dtsi6
-rw-r--r--arch/arm/boot/dts/bcm283x.dtsi212
-rw-r--r--arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts64
-rw-r--r--arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts2
-rw-r--r--arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts2
-rw-r--r--arch/arm/boot/dts/bcm4709-netgear-r7000.dts2
-rw-r--r--arch/arm/boot/dts/bcm4709-netgear-r8000.dts6
-rw-r--r--arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts114
-rw-r--r--arch/arm/boot/dts/bcm4709.dtsi11
-rw-r--r--arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts3
-rw-r--r--arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts111
-rw-r--r--arch/arm/boot/dts/bcm47094-netgear-r8500.dts103
-rw-r--r--arch/arm/boot/dts/bcm47094.dtsi17
-rw-r--r--arch/arm/boot/dts/bcm47189-tenda-ac9.dts74
-rw-r--r--arch/arm/boot/dts/bcm5301x-nand-cs0-bch4.dtsi13
-rw-r--r--arch/arm/boot/dts/bcm5301x.dtsi7
-rw-r--r--arch/arm/boot/dts/bcm53573.dtsi159
-rw-r--r--arch/arm/boot/dts/bcm958625k.dts34
-rw-r--r--arch/arm/boot/dts/berlin2q-marvell-dmp.dts12
-rw-r--r--arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts94
-rw-r--r--arch/arm/boot/dts/da850-lcdk.dts19
-rw-r--r--arch/arm/boot/dts/da850.dtsi70
-rw-r--r--arch/arm/boot/dts/dm814x.dtsi1
-rw-r--r--arch/arm/boot/dts/dm816x.dtsi2
-rw-r--r--arch/arm/boot/dts/dra7.dtsi1
-rw-r--r--arch/arm/boot/dts/dra71-evm.dts230
-rw-r--r--arch/arm/boot/dts/dra72-evm-common.dtsi348
-rw-r--r--arch/arm/boot/dts/dra72-evm-revc.dts21
-rw-r--r--arch/arm/boot/dts/dra72-evm-tps65917.dtsi134
-rw-r--r--arch/arm/boot/dts/dra72-evm.dts14
-rw-r--r--arch/arm/boot/dts/emev2.dtsi3
-rw-r--r--arch/arm/boot/dts/exynos3250-artik5-eval.dts2
-rw-r--r--arch/arm/boot/dts/exynos3250-artik5.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos3250-monk.dts2
-rw-r--r--arch/arm/boot/dts/exynos3250-pinctrl.dtsi20
-rw-r--r--arch/arm/boot/dts/exynos3250-rinato.dts2
-rw-r--r--arch/arm/boot/dts/exynos3250.dtsi97
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi100
-rw-r--r--arch/arm/boot/dts/exynos4210-pinctrl.dtsi20
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi36
-rw-r--r--arch/arm/boot/dts/exynos4412-itop-elite.dts240
-rw-r--r--arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi501
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidx.dts5
-rw-r--r--arch/arm/boot/dts/exynos4415-pinctrl.dtsi575
-rw-r--r--arch/arm/boot/dts/exynos4415.dtsi650
-rw-r--r--arch/arm/boot/dts/exynos4x12-pinctrl.dtsi20
-rw-r--r--arch/arm/boot/dts/exynos4x12.dtsi50
-rw-r--r--arch/arm/boot/dts/exynos5.dtsi64
-rw-r--r--arch/arm/boot/dts/exynos5250-snow-common.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi80
-rw-r--r--arch/arm/boot/dts/exynos5260.dtsi43
-rw-r--r--arch/arm/boot/dts/exynos5410-odroidxu.dts69
-rw-r--r--arch/arm/boot/dts/exynos5410-pinctrl.dtsi9
-rw-r--r--arch/arm/boot/dts/exynos5410.dtsi85
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts3
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi78
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi12
-rw-r--r--arch/arm/boot/dts/exynos5440.dtsi72
-rw-r--r--arch/arm/boot/dts/exynos54xx.dtsi34
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts3
-rw-r--r--arch/arm/boot/dts/hi3620.dtsi6
-rw-r--r--arch/arm/boot/dts/hip01.dtsi2
-rw-r--r--arch/arm/boot/dts/hisi-x5hd2.dtsi4
-rw-r--r--arch/arm/boot/dts/imx1.dtsi4
-rw-r--r--arch/arm/boot/dts/imx23.dtsi6
-rw-r--r--arch/arm/boot/dts/imx25.dtsi4
-rw-r--r--arch/arm/boot/dts/imx27.dtsi4
-rw-r--r--arch/arm/boot/dts/imx28-m28.dtsi4
-rw-r--r--arch/arm/boot/dts/imx28-m28evk.dts4
-rw-r--r--arch/arm/boot/dts/imx28.dtsi4
-rw-r--r--arch/arm/boot/dts/imx31.dtsi19
-rw-r--r--arch/arm/boot/dts/imx35.dtsi4
-rw-r--r--arch/arm/boot/dts/imx50.dtsi48
-rw-r--r--arch/arm/boot/dts/imx51.dtsi48
-rw-r--r--arch/arm/boot/dts/imx53-m53.dtsi4
-rw-r--r--arch/arm/boot/dts/imx53-m53evk.dts4
-rw-r--r--arch/arm/boot/dts/imx53.dtsi72
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts253
-rw-r--r--arch/arm/boot/dts/imx6dl-icore.dts59
-rw-r--r--arch/arm/boot/dts/imx6dl-riotboard.dts2
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts2
-rw-r--r--arch/arm/boot/dts/imx6dl-tx6u-801x.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora.dts22
-rw-r--r--arch/arm/boot/dts/imx6q-b650v3.dts6
-rw-r--r--arch/arm/boot/dts/imx6q-cm-fx6.dts1
-rw-r--r--arch/arm/boot/dts/imx6q-evi.dts3
-rw-r--r--arch/arm/boot/dts/imx6q-icore.dts59
-rw-r--r--arch/arm/boot/dts/imx6q-nitrogen6_som2.dts53
-rw-r--r--arch/arm/boot/dts/imx6q-novena.dts4
-rw-r--r--arch/arm/boot/dts/imx6q-phytec-pbab01.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1010.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-tx6q-1020.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-utilite-pro.dts53
-rw-r--r--arch/arm/boot/dts/imx6qdl-apalis.dtsi9
-rw-r--r--arch/arm/boot/dts/imx6qdl-apf6dev.dtsi14
-rw-r--r--arch/arm/boot/dts/imx6qdl-colibri.dtsi890
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw52xx.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw53xx.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw54xx.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw552x.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-icore.dtsi265
-rw-r--r--arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi32
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi18
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi770
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi12
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi6
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabreauto.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabrelite.dtsi10
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-tx6.dtsi32
-rw-r--r--arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-wandboard.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi14
-rw-r--r--arch/arm/boot/dts/imx6qp.dtsi17
-rw-r--r--arch/arm/boot/dts/imx6sl.dtsi7
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dtsi16
-rw-r--r--arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts69
-rw-r--r--arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts54
-rw-r--r--arch/arm/boot/dts/imx6sx-udoo-neo-full.dts69
-rw-r--r--arch/arm/boot/dts/imx6sx-udoo-neo.dtsi293
-rw-r--r--arch/arm/boot/dts/imx6sx.dtsi17
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk.dts10
-rw-r--r--arch/arm/boot/dts/imx6ul-liteboard.dts147
-rw-r--r--arch/arm/boot/dts/imx6ul-litesom.dtsi82
-rw-r--r--arch/arm/boot/dts/imx6ul.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6ull-14x14-evk.dts52
-rw-r--r--arch/arm/boot/dts/imx6ull-pinfunc.h56
-rw-r--r--arch/arm/boot/dts/imx6ull.dtsi43
-rw-r--r--arch/arm/boot/dts/imx7d-pinfunc.h12
-rw-r--r--arch/arm/boot/dts/imx7s.dtsi4
-rw-r--r--arch/arm/boot/dts/integratorap.dts35
-rw-r--r--arch/arm/boot/dts/integratorcp.dts26
-rw-r--r--arch/arm/boot/dts/keystone-k2g.dtsi1
-rw-r--r--arch/arm/boot/dts/keystone-k2l.dtsi1
-rw-r--r--arch/arm/boot/dts/kirkwood-topkick.dts2
-rw-r--r--arch/arm/boot/dts/lpc32xx.dtsi4
-rw-r--r--arch/arm/boot/dts/ls1021a.dtsi84
-rw-r--r--arch/arm/boot/dts/mps2-an385.dts2
-rw-r--r--arch/arm/boot/dts/mps2-an399.dts2
-rw-r--r--arch/arm/boot/dts/mps2.dtsi4
-rw-r--r--arch/arm/boot/dts/mt2701.dtsi50
-rw-r--r--arch/arm/boot/dts/omap2420.dtsi2
-rw-r--r--arch/arm/boot/dts/omap2430.dtsi2
-rw-r--r--arch/arm/boot/dts/omap3.dtsi2
-rw-r--r--arch/arm/boot/dts/omap34xx.dtsi1
-rw-r--r--arch/arm/boot/dts/omap36xx.dtsi1
-rw-r--r--arch/arm/boot/dts/omap4-droid4-xt894.dts188
-rw-r--r--arch/arm/boot/dts/omap4.dtsi2
-rw-r--r--arch/arm/boot/dts/omap5-uevm.dts92
-rw-r--r--arch/arm/boot/dts/omap5.dtsi2
-rw-r--r--arch/arm/boot/dts/orion5x-lschl.dts171
-rw-r--r--arch/arm/boot/dts/ox820.dtsi296
-rw-r--r--arch/arm/boot/dts/pxa25x.dtsi117
-rw-r--r--arch/arm/boot/dts/pxa27x.dtsi40
-rw-r--r--arch/arm/boot/dts/pxa2xx.dtsi4
-rw-r--r--arch/arm/boot/dts/pxa3xx.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom-apq8060-dragonboard.dts119
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts77
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-ifc6410.dts74
-rw-r--r--arch/arm/boot/dts/qcom-apq8064.dtsi321
-rw-r--r--arch/arm/boot/dts/qcom-apq8084.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom-mdm9615-wp8548-mangoh-green.dts281
-rw-r--r--arch/arm/boot/dts/qcom-mdm9615-wp8548.dtsi170
-rw-r--r--arch/arm/boot/dts/qcom-mdm9615.dtsi557
-rw-r--r--arch/arm/boot/dts/qcom-msm8660.dtsi17
-rw-r--r--arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts29
-rw-r--r--arch/arm/boot/dts/qcom-msm8974.dtsi16
-rw-r--r--arch/arm/boot/dts/r7s72100-rskrza1.dts5
-rw-r--r--arch/arm/boot/dts/r7s72100.dtsi55
-rw-r--r--arch/arm/boot/dts/r8a73a4.dtsi5
-rw-r--r--arch/arm/boot/dts/r8a7740.dtsi4
-rw-r--r--arch/arm/boot/dts/r8a7743-sk-rzg1m.dts57
-rw-r--r--arch/arm/boot/dts/r8a7743.dtsi476
-rw-r--r--arch/arm/boot/dts/r8a7745-sk-rzg1e.dts52
-rw-r--r--arch/arm/boot/dts/r8a7745.dtsi476
-rw-r--r--arch/arm/boot/dts/r8a7778.dtsi4
-rw-r--r--arch/arm/boot/dts/r8a7779-marzen.dts2
-rw-r--r--arch/arm/boot/dts/r8a7779.dtsi11
-rw-r--r--arch/arm/boot/dts/r8a7790-lager.dts118
-rw-r--r--arch/arm/boot/dts/r8a7790.dtsi11
-rw-r--r--arch/arm/boot/dts/r8a7791-koelsch.dts137
-rw-r--r--arch/arm/boot/dts/r8a7791.dtsi14
-rw-r--r--arch/arm/boot/dts/r8a7792-wheat.dts126
-rw-r--r--arch/arm/boot/dts/r8a7792.dtsi56
-rw-r--r--arch/arm/boot/dts/r8a7793-gose.dts12
-rw-r--r--arch/arm/boot/dts/r8a7793.dtsi38
-rw-r--r--arch/arm/boot/dts/r8a7794-alt.dts62
-rw-r--r--arch/arm/boot/dts/r8a7794.dtsi81
-rw-r--r--arch/arm/boot/dts/rk1108-evb.dts69
-rw-r--r--arch/arm/boot/dts/rk1108.dtsi452
-rw-r--r--arch/arm/boot/dts/rk3036-evb.dts2
-rw-r--r--arch/arm/boot/dts/rk3036-kylin.dts2
-rw-r--r--arch/arm/boot/dts/rk3036.dtsi10
-rw-r--r--arch/arm/boot/dts/rk3066a-bqcurie2.dts2
-rw-r--r--arch/arm/boot/dts/rk3066a-marsboard.dts2
-rw-r--r--arch/arm/boot/dts/rk3066a-mk808.dts195
-rw-r--r--arch/arm/boot/dts/rk3066a-rayeager.dts2
-rw-r--r--arch/arm/boot/dts/rk3066a.dtsi31
-rw-r--r--arch/arm/boot/dts/rk3188-px3-evb.dts328
-rw-r--r--arch/arm/boot/dts/rk3188-radxarock.dts2
-rw-r--r--arch/arm/boot/dts/rk3188.dtsi2
-rw-r--r--arch/arm/boot/dts/rk3228-evb.dts2
-rw-r--r--arch/arm/boot/dts/rk3229-evb.dts2
-rw-r--r--arch/arm/boot/dts/rk322x.dtsi6
-rw-r--r--arch/arm/boot/dts/rk3288-evb.dtsi2
-rw-r--r--arch/arm/boot/dts/rk3288-fennec.dts2
-rw-r--r--arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi2
-rw-r--r--arch/arm/boot/dts/rk3288-firefly.dtsi2
-rw-r--r--arch/arm/boot/dts/rk3288-miqi.dts2
-rw-r--r--arch/arm/boot/dts/rk3288-popmetal.dts34
-rw-r--r--arch/arm/boot/dts/rk3288-r89.dts2
-rw-r--r--arch/arm/boot/dts/rk3288-rock2-som.dtsi2
-rw-r--r--arch/arm/boot/dts/rk3288-veyron.dtsi2
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi14
-rw-r--r--arch/arm/boot/dts/rk3xxx.dtsi4
-rw-r--r--arch/arm/boot/dts/sama5d2.dtsi47
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi4
-rw-r--r--arch/arm/boot/dts/sama5d4.dtsi31
-rw-r--r--arch/arm/boot/dts/sh73a0.dtsi4
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi33
-rw-r--r--arch/arm/boot/dts/socfpga_arria10.dtsi32
-rw-r--r--arch/arm/boot/dts/socfpga_arria10_socdk.dtsi49
-rw-r--r--arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts49
-rw-r--r--arch/arm/boot/dts/socfpga_arria5_socdk.dts33
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts2
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi2
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts4
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socdk.dts35
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sockit.dts23
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socrates.dts19
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sodia.dts123
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts2
-rw-r--r--arch/arm/boot/dts/spear13xx.dtsi2
-rw-r--r--arch/arm/boot/dts/stih407-clock.dtsi10
-rw-r--r--arch/arm/boot/dts/stih407-family.dtsi32
-rw-r--r--arch/arm/boot/dts/stih407-pinctrl.dtsi2
-rw-r--r--arch/arm/boot/dts/stih407.dtsi2
-rw-r--r--arch/arm/boot/dts/stih410-b2260.dts22
-rw-r--r--arch/arm/boot/dts/stih410-clock.dtsi3
-rw-r--r--arch/arm/boot/dts/stih410.dtsi2
-rw-r--r--arch/arm/boot/dts/stih415-b2000.dts15
-rw-r--r--arch/arm/boot/dts/stih415-b2020.dts15
-rw-r--r--arch/arm/boot/dts/stih415-clock.dtsi533
-rw-r--r--arch/arm/boot/dts/stih415-pinctrl.dtsi545
-rw-r--r--arch/arm/boot/dts/stih415.dtsi234
-rw-r--r--arch/arm/boot/dts/stih416-b2000.dts15
-rw-r--r--arch/arm/boot/dts/stih416-b2020.dts37
-rw-r--r--arch/arm/boot/dts/stih416-b2020e.dts65
-rw-r--r--arch/arm/boot/dts/stih416-clock.dtsi756
-rw-r--r--arch/arm/boot/dts/stih416-pinctrl.dtsi692
-rw-r--r--arch/arm/boot/dts/stih416.dtsi517
-rw-r--r--arch/arm/boot/dts/stih41x-b2000.dtsi96
-rw-r--r--arch/arm/boot/dts/stih41x-b2020.dtsi82
-rw-r--r--arch/arm/boot/dts/stih41x-b2020x.dtsi32
-rw-r--r--arch/arm/boot/dts/stih41x.dtsi47
-rw-r--r--arch/arm/boot/dts/stihxxx-b2120.dtsi21
-rw-r--r--arch/arm/boot/dts/stm32429i-eval.dts29
-rw-r--r--arch/arm/boot/dts/stm32746g-eval.dts96
-rw-r--r--arch/arm/boot/dts/stm32f429-disco.dts13
-rw-r--r--arch/arm/boot/dts/stm32f429.dtsi40
-rw-r--r--arch/arm/boot/dts/stm32f469-disco.dts8
-rw-r--r--arch/arm/boot/dts/stm32f746.dtsi304
-rw-r--r--arch/arm/boot/dts/sun4i-a10.dtsi3
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts4
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi4
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino.dts54
-rw-r--r--arch/arm/boot/dts/sun5i-a13-utoo-p66.dts38
-rw-r--r--arch/arm/boot/dts/sun5i-gr8-chip-pro.dts266
-rw-r--r--arch/arm/boot/dts/sun5i-gr8-evb.dts33
-rw-r--r--arch/arm/boot/dts/sun5i-gr8.dtsi47
-rw-r--r--arch/arm/boot/dts/sun5i-r8-chip.dts69
-rw-r--r--arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi25
-rw-r--r--arch/arm/boot/dts/sun5i.dtsi27
-rw-r--r--arch/arm/boot/dts/sun6i-a31-hummingbird.dts80
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi266
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-sina31s.dts8
-rw-r--r--arch/arm/boot/dts/sun6i-a31s.dtsi8
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts62
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts4
-rw-r--r--arch/arm/boot/dts/sun7i-a20.dtsi3
-rw-r--r--arch/arm/boot/dts/sun8i-a23-a33.dtsi6
-rw-r--r--arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts7
-rw-r--r--arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts5
-rw-r--r--arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts64
-rw-r--r--arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts79
-rw-r--r--arch/arm/boot/dts/sun8i-h3-nanopi.dtsi144
-rw-r--r--arch/arm/boot/dts/sun8i-h3.dtsi52
-rw-r--r--arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi7
-rw-r--r--arch/arm/boot/dts/sun9i-a80-cubieboard4.dts32
-rw-r--r--arch/arm/boot/dts/sun9i-a80-optimus.dts30
-rw-r--r--arch/arm/boot/dts/sun9i-a80.dtsi14
-rw-r--r--arch/arm/boot/dts/tegra124-apalis.dtsi2
-rw-r--r--arch/arm/boot/dts/tegra124-nyan.dtsi8
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi13
-rw-r--r--arch/arm/boot/dts/tegra30-apalis.dtsi49
-rw-r--r--arch/arm/boot/dts/tegra30-colibri.dtsi49
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi13
-rw-r--r--arch/arm/boot/dts/tps65217.dtsi12
-rw-r--r--arch/arm/boot/dts/uniphier-common32.dtsi199
-rw-r--r--arch/arm/boot/dts/uniphier-ld4.dtsi358
-rw-r--r--arch/arm/boot/dts/uniphier-pro4.dtsi378
-rw-r--r--arch/arm/boot/dts/uniphier-pro5.dtsi432
-rw-r--r--arch/arm/boot/dts/uniphier-pxs2.dtsi399
-rw-r--r--arch/arm/boot/dts/uniphier-sld3.dtsi21
-rw-r--r--arch/arm/boot/dts/uniphier-sld8.dtsi359
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts5
-rw-r--r--arch/arm/boot/dts/vf-colibri.dtsi4
-rw-r--r--arch/arm/boot/dts/vf610-zii-dev-rev-b.dts14
-rw-r--r--arch/arm/boot/dts/vfxxx.dtsi18
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi10
-rw-r--r--arch/arm/boot/dts/zynq-microzed.dts96
-rw-r--r--arch/arm/boot/dts/zynq-parallella.dts2
-rw-r--r--arch/arm/boot/dts/zynq-zc702.dts2
-rw-r--r--arch/arm/boot/dts/zynq-zc706.dts2
-rw-r--r--arch/arm/boot/dts/zynq-zed.dts2
-rw-r--r--arch/arm/boot/dts/zynq-zybo.dts2
-rw-r--r--arch/arm/configs/am200epdkit_defconfig5
-rw-r--r--arch/arm/configs/assabet_defconfig1
-rw-r--r--arch/arm/configs/badge4_defconfig2
-rw-r--r--arch/arm/configs/bcm2835_defconfig2
-rw-r--r--arch/arm/configs/cerfcube_defconfig1
-rw-r--r--arch/arm/configs/collie_defconfig5
-rw-r--r--arch/arm/configs/corgi_defconfig7
-rw-r--r--arch/arm/configs/davinci_all_defconfig20
-rw-r--r--arch/arm/configs/dram_0xc0000000.config1
-rw-r--r--arch/arm/configs/exynos_defconfig1
-rw-r--r--arch/arm/configs/h3600_defconfig5
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig2
-rw-r--r--arch/arm/configs/integrator_defconfig1
-rw-r--r--arch/arm/configs/ixp4xx_defconfig9
-rw-r--r--arch/arm/configs/jornada720_defconfig5
-rw-r--r--arch/arm/configs/lart_defconfig2
-rw-r--r--arch/arm/configs/mainstone_defconfig1
-rw-r--r--arch/arm/configs/multi_v5_defconfig1
-rw-r--r--arch/arm/configs/multi_v7_defconfig20
-rw-r--r--arch/arm/configs/netwinder_defconfig7
-rw-r--r--arch/arm/configs/omap1_defconfig4
-rw-r--r--arch/arm/configs/omap2plus_defconfig12
-rw-r--r--arch/arm/configs/qcom_defconfig4
-rw-r--r--arch/arm/configs/s3c2410_defconfig10
-rw-r--r--arch/arm/configs/shannon_defconfig1
-rw-r--r--arch/arm/configs/shmobile_defconfig1
-rw-r--r--arch/arm/configs/socfpga_defconfig15
-rw-r--r--arch/arm/configs/spitz_defconfig8
-rw-r--r--arch/arm/configs/stm32_defconfig3
-rw-r--r--arch/arm/configs/sunxi_defconfig1
-rw-r--r--arch/arm/configs/tegra_defconfig27
-rw-r--r--arch/arm/configs/u8500_defconfig7
-rw-r--r--arch/arm/include/asm/Kbuild3
-rw-r--r--arch/arm/include/asm/delay.h27
-rw-r--r--arch/arm/include/asm/mach-types.h1
-rw-r--r--arch/arm/include/asm/unistd.h26
-rw-r--r--arch/arm/include/uapi/asm/Kbuild3
-rw-r--r--arch/arm/include/uapi/asm/unistd.h424
-rw-r--r--arch/arm/kernel/calls.S415
-rw-r--r--arch/arm/kernel/entry-common.S76
-rw-r--r--arch/arm/kernel/topology.c220
-rw-r--r--arch/arm/lib/delay-loop.S15
-rw-r--r--arch/arm/mach-artpec/Kconfig1
-rw-r--r--arch/arm/mach-bcm/bcm_5301x.c28
-rw-r--r--arch/arm/mach-davinci/Makefile4
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c95
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c56
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c20
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c68
-rw-r--r--arch/arm/mach-davinci/common.c1
-rw-r--r--arch/arm/mach-davinci/da830.c4
-rw-r--r--arch/arm/mach-davinci/da850.c90
-rw-r--r--arch/arm/mach-davinci/da8xx-dt.c26
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c57
-rw-r--r--arch/arm/mach-davinci/devices.c3
-rw-r--r--arch/arm/mach-davinci/dm355.c8
-rw-r--r--arch/arm/mach-davinci/dm365.c8
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h7
-rw-r--r--arch/arm/mach-davinci/pm.c102
-rw-r--r--arch/arm/mach-davinci/usb-da8xx.c280
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/common.h1
-rw-r--r--arch/arm/mach-imx/imx31-dt.c6
-rw-r--r--arch/arm/mach-imx/mach-imx6ul.c1
-rw-r--r--arch/arm/mach-imx/mmdc.c495
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c54
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c1
-rw-r--r--arch/arm/mach-lpc32xx/clock.h38
-rw-r--r--arch/arm/mach-lpc32xx/common.h1
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/irqs.h117
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c1
-rw-r--r--arch/arm/mach-lpc32xx/pm.c1
-rw-r--r--arch/arm/mach-mediatek/Makefile6
-rw-r--r--arch/arm/mach-omap1/Kconfig26
-rw-r--r--arch/arm/mach-omap1/i2c.c83
-rw-r--r--arch/arm/mach-omap2/Makefile18
-rw-r--r--arch/arm/mach-omap2/board-flash.c242
-rw-r--r--arch/arm/mach-omap2/board-flash.h56
-rw-r--r--arch/arm/mach-omap2/board-generic.c3
-rw-r--r--arch/arm/mach-omap2/clockdomains7xx_data.c2
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c102
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h8
-rw-r--r--arch/arm/mach-omap2/common.h48
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c80
-rw-r--r--arch/arm/mach-omap2/devices.c1
-rw-r--r--arch/arm/mach-omap2/display.c5
-rw-r--r--arch/arm/mach-omap2/dss-common.c37
-rw-r--r--arch/arm/mach-omap2/dss-common.h13
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c100
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.h35
-rw-r--r--arch/arm/mach-omap2/hsmmc.c88
-rw-r--r--arch/arm/mach-omap2/i2c.c97
-rw-r--r--arch/arm/mach-omap2/io.c4
-rw-r--r--arch/arm/mach-omap2/msdi.c1
-rw-r--r--arch/arm/mach-omap2/mux.c1153
-rw-r--r--arch/arm/mach-omap2/mux.h352
-rw-r--r--arch/arm/mach-omap2/mux34xx.c2061
-rw-r--r--arch/arm/mach-omap2/mux34xx.h402
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c37
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c107
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c149
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c201
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c1
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c29
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_data.c35
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c787
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c34
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c182
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h15
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c1
-rw-r--r--arch/arm/mach-omap2/pm-debug.c5
-rw-r--r--arch/arm/mach-omap2/pm.c66
-rw-r--r--arch/arm/mach-omap2/pm44xx.c2
-rw-r--r--arch/arm/mach-omap2/prcm43xx.h2
-rw-r--r--arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h51
-rw-r--r--arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h55
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.c299
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.h12
-rw-r--r--arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h51
-rw-r--r--arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h54
-rw-r--r--arch/arm/mach-omap2/serial.c332
-rw-r--r--arch/arm/mach-omap2/twl-common.c564
-rw-r--r--arch/arm/mach-omap2/twl-common.h66
-rw-r--r--arch/arm/mach-omap2/usb-host.c496
-rw-r--r--arch/arm/mach-omap2/usb-musb.c106
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c21
-rw-r--r--arch/arm/mach-orion5x/Kconfig7
-rw-r--r--arch/arm/mach-orion5x/Makefile1
-rw-r--r--arch/arm/mach-orion5x/ls-chl-setup.c331
-rw-r--r--arch/arm/mach-oxnas/Kconfig30
-rw-r--r--arch/arm/mach-oxnas/Makefile2
-rw-r--r--arch/arm/mach-oxnas/headsmp.S26
-rw-r--r--arch/arm/mach-oxnas/hotplug.c109
-rw-r--r--arch/arm/mach-oxnas/platsmp.c102
-rw-r--r--arch/arm/mach-pxa/corgi.c1
-rw-r--r--arch/arm/mach-pxa/em-x270.c89
-rw-r--r--arch/arm/mach-pxa/ezx.c176
-rw-r--r--arch/arm/mach-pxa/generic.c18
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-pxa/mioa701.c13
-rw-r--r--arch/arm/mach-pxa/pxa25x.c2
-rw-r--r--arch/arm/mach-pxa/pxa_cplds_irqs.c11
-rw-r--r--arch/arm/mach-pxa/spitz.c1
-rw-r--r--arch/arm/mach-s3c64xx/pl080.c32
-rw-r--r--arch/arm/mach-sa1100/generic.c2
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1101.h925
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h8
-rw-r--r--arch/arm/mach-shmobile/Kconfig21
-rw-r--r--arch/arm/mach-shmobile/Makefile3
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7792.c35
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7793.c33
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7794.c33
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c34
-rw-r--r--arch/arm/mach-socfpga/l2_cache.c2
-rw-r--r--arch/arm/mach-spear/time.c2
-rw-r--r--arch/arm/mach-sti/Kconfig2
-rw-r--r--arch/arm/mach-stm32/board-dt.c1
-rw-r--r--arch/arm/mach-vexpress/platsmp.c34
-rw-r--r--arch/arm/mach-zx/zx296702-pm-domain.c2
-rw-r--r--arch/arm/mach-zynq/common.c2
-rw-r--r--arch/arm/mm/Kconfig8
-rw-r--r--arch/arm/mm/pageattr.c27
-rw-r--r--arch/arm/plat-omap/Kconfig26
-rw-r--r--arch/arm/plat-omap/Makefile3
-rw-r--r--arch/arm/plat-omap/i2c.c116
-rw-r--r--arch/arm/plat-orion/gpio.c6
-rw-r--r--arch/arm/plat-samsung/devs.c24
-rw-r--r--arch/arm/tools/Makefile68
-rw-r--r--arch/arm/tools/mach-types516
-rw-r--r--arch/arm/tools/syscall.tbl413
-rw-r--r--arch/arm/tools/syscallhdr.sh30
-rw-r--r--arch/arm/tools/syscallnr.sh33
-rw-r--r--arch/arm/tools/syscalltbl.sh21
-rw-r--r--arch/arm/vfp/vfp.h10
-rw-r--r--arch/arm/vfp/vfpmodule.c8
-rw-r--r--arch/arm64/Kconfig.platforms2
-rw-r--r--arch/arm64/boot/dts/Makefile1
-rw-r--r--arch/arm64/boot/dts/allwinner/Makefile5
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts50
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts74
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi261
-rw-r--r--arch/arm64/boot/dts/amlogic/Makefile8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi190
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx.dtsi360
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts231
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts119
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi129
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi106
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi901
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts205
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts77
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts58
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi48
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts69
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi54
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl.dtsi301
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts169
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts77
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm-s912-q201.dts58
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm.dtsi114
-rw-r--r--arch/arm64/boot/dts/arm/juno-base.dtsi80
-rw-r--r--arch/arm64/boot/dts/arm/juno-r1.dts6
-rw-r--r--arch/arm64/boot/dts/arm/juno-r2.dts6
-rw-r--r--arch/arm64/boot/dts/arm/juno.dts6
-rw-r--r--arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts8
-rw-r--r--arch/arm64/boot/dts/broadcom/bcm2837.dtsi8
l---------arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi1
-rw-r--r--arch/arm64/boot/dts/broadcom/ns2-svk.dts38
-rw-r--r--arch/arm64/boot/dts/broadcom/ns2.dtsi62
-rw-r--r--arch/arm64/boot/dts/exynos/Makefile5
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi804
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tm2.dts1049
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts41
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi23
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi22
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi296
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433.dtsi1462
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi20
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7.dtsi87
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi78
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts212
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts150
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi515
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi116
-rw-r--r--arch/arm64/boot/dts/hisilicon/Makefile1
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220.dtsi3
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip06-d03.dts8
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip06.dtsi23
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip07-d05.dts66
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip07.dtsi1059
-rw-r--r--arch/arm64/boot/dts/marvell/Makefile1
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-db.dts2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts82
-rw-r--r--arch/arm64/boot/dts/marvell/armada-37xx.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-ap806.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts2
-rw-r--r--arch/arm64/boot/dts/marvell/berlin4ct-stb.dts2
-rw-r--r--arch/arm64/boot/dts/marvell/berlin4ct.dtsi2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173.dtsi3
-rw-r--r--arch/arm64/boot/dts/nvidia/Makefile1
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts8
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi64
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra186.dtsi398
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi18
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts26
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-smaug.dts3
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210.dtsi63
-rw-r--r--arch/arm64/boot/dts/qcom/Makefile7
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi73
-rw-r--r--arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi15
-rw-r--r--arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi73
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts41
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992-pins.dtsi38
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992.dtsi184
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts40
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994-pins.dtsi38
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994.dtsi216
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi91
-rw-r--r--arch/arm64/boot/dts/qcom/pm8916.dtsi45
-rw-r--r--arch/arm64/boot/dts/qcom/pm8994.dtsi1
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts53
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts85
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795.dtsi29
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts189
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts160
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7796.dtsi255
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts314
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368.dtsi18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-evb.dts40
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399.dtsi55
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi59
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi111
-rw-r--r--arch/arm64/boot/dts/zte/zx296718.dtsi33
-rw-r--r--arch/arm64/configs/defconfig55
-rw-r--r--arch/arm64/kernel/pci.c67
-rw-r--r--arch/arm64/mm/dma-mapping.c2
-rw-r--r--arch/powerpc/include/asm/trace.h4
-rw-r--r--arch/powerpc/platforms/powernv/opal-tracepoints.c6
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c6
-rw-r--r--arch/x86/entry/entry_32.S4
-rw-r--r--arch/x86/include/asm/trace/exceptions.h2
-rw-r--r--arch/x86/include/asm/trace/irq_vectors.h2
-rw-r--r--arch/x86/kernel/tracepoint.c3
-rw-r--r--crypto/asymmetric_keys/public_key.c1
-rw-r--r--crypto/skcipher.c4
-rw-r--r--drivers/acpi/arm64/iort.c607
-rw-r--r--drivers/acpi/glue.c4
-rw-r--r--drivers/acpi/pci_mcfg.c190
-rw-r--r--drivers/acpi/resource.c57
-rw-r--r--drivers/acpi/scan.c33
-rw-r--r--drivers/bus/Kconfig16
-rw-r--r--drivers/bus/Makefile3
-rw-r--r--drivers/bus/arm-cci.c10
-rw-r--r--drivers/bus/da8xx-mstpri.c267
-rw-r--r--drivers/bus/tegra-gmi.c284
-rw-r--r--drivers/bus/vexpress-config.c7
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c10
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c190
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c37
-rw-r--r--drivers/clk/clkdev.c8
-rw-r--r--drivers/clk/imx/clk-imx31.c52
-rw-r--r--drivers/clk/pxa/clk-pxa25x.c2
-rw-r--r--drivers/clocksource/Kconfig20
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/arc_timer.c (renamed from arch/arc/kernel/time.c)110
-rw-r--r--drivers/clocksource/pxa_timer.c11
-rw-r--r--drivers/clocksource/timer-nps.c224
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/amba-pl08x.c11
-rw-r--r--drivers/dma/at_hdmac.c3
-rw-r--r--drivers/dma/at_xdmac.c5
-rw-r--r--drivers/dma/dmatest.c74
-rw-r--r--drivers/dma/dw/core.c2
-rw-r--r--drivers/dma/dw/platform.c18
-rw-r--r--drivers/dma/dw/regs.h3
-rw-r--r--drivers/dma/edma.c3
-rw-r--r--drivers/dma/fsl_raid.c1
-rw-r--r--drivers/dma/hsu/pci.c8
-rw-r--r--drivers/dma/img-mdc-dma.c9
-rw-r--r--drivers/dma/imx-sdma.c13
-rw-r--r--drivers/dma/ioat/dma.c17
-rw-r--r--drivers/dma/ioat/init.c21
-rw-r--r--drivers/dma/k3dma.c3
-rw-r--r--drivers/dma/mic_x100_dma.c2
-rw-r--r--drivers/dma/mv_xor.c190
-rw-r--r--drivers/dma/mv_xor.h1
-rw-r--r--drivers/dma/nbpfaxi.c38
-rw-r--r--drivers/dma/omap-dma.c187
-rw-r--r--drivers/dma/pch_dma.c5
-rw-r--r--drivers/dma/pl330.c23
-rw-r--r--drivers/dma/pxa_dma.c28
-rw-r--r--drivers/dma/qcom/hidma.c173
-rw-r--r--drivers/dma/qcom/hidma.h9
-rw-r--r--drivers/dma/qcom/hidma_dbg.c4
-rw-r--r--drivers/dma/qcom/hidma_ll.c176
-rw-r--r--drivers/dma/qcom/hidma_mgmt.c11
-rw-r--r--drivers/dma/s3c24xx-dma.c5
-rw-r--r--drivers/dma/sh/usb-dmac.c3
-rw-r--r--drivers/dma/sirf-dma.c4
-rw-r--r--drivers/dma/stm32-dma.c6
-rw-r--r--drivers/dma/zx296702_dma.c3
-rw-r--r--drivers/firmware/Kconfig27
-rw-r--r--drivers/firmware/Makefile3
-rw-r--r--drivers/firmware/arm_scpi.c276
-rw-r--r--drivers/firmware/psci.c2
-rw-r--r--drivers/firmware/psci_checker.c490
-rw-r--r--drivers/firmware/qcom_scm.c53
-rw-r--r--drivers/firmware/tegra/Kconfig25
-rw-r--r--drivers/firmware/tegra/Makefile2
-rw-r--r--drivers/firmware/tegra/bpmp.c868
-rw-r--r--drivers/firmware/tegra/ivc.c695
-rw-r--r--drivers/firmware/ti_sci.c1991
-rw-r--r--drivers/firmware/ti_sci.h492
-rw-r--r--drivers/hwtracing/coresight/coresight-stm.c2
-rw-r--r--drivers/hwtracing/intel_th/sth.c11
-rw-r--r--drivers/hwtracing/stm/Kconfig11
-rw-r--r--drivers/hwtracing/stm/Makefile2
-rw-r--r--drivers/hwtracing/stm/core.c7
-rw-r--r--drivers/hwtracing/stm/dummy_stm.c2
-rw-r--r--drivers/hwtracing/stm/ftrace.c87
-rw-r--r--drivers/i2c/Kconfig1
-rw-r--r--drivers/i2c/busses/Kconfig25
-rw-r--r--drivers/i2c/busses/Makefile2
-rw-r--r--drivers/i2c/busses/i2c-axxia.c2
-rw-r--r--drivers/i2c/busses/i2c-bcm-iproc.c2
-rw-r--r--drivers/i2c/busses/i2c-bcm2835.c218
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c46
-rw-r--r--drivers/i2c/busses/i2c-designware-core.h8
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c10
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c23
-rw-r--r--drivers/i2c/busses/i2c-dln2.c2
-rw-r--r--drivers/i2c/busses/i2c-i801.c123
-rw-r--r--drivers/i2c/busses/i2c-imx-lpi2c.c652
-rw-r--r--drivers/i2c/busses/i2c-mlxcpld.c504
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.c46
-rw-r--r--drivers/i2c/busses/i2c-pxa-pci.c32
-rw-r--r--drivers/i2c/busses/i2c-pxa.c26
-rw-r--r--drivers/i2c/busses/i2c-qup.c122
-rw-r--r--drivers/i2c/busses/i2c-rcar.c5
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c4
-rw-r--r--drivers/i2c/busses/i2c-uniphier-f.c6
-rw-r--r--drivers/i2c/busses/i2c-uniphier.c6
-rw-r--r--drivers/i2c/busses/i2c-viperboard.c2
-rw-r--r--drivers/i2c/busses/i2c-xlp9xx.c1
-rw-r--r--drivers/i2c/i2c-core.c200
-rw-r--r--drivers/i2c/i2c-smbus.c102
-rw-r--r--drivers/i2c/muxes/Kconfig11
-rw-r--r--drivers/i2c/muxes/Makefile1
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpio.c18
-rw-r--r--drivers/i2c/muxes/i2c-mux-mlxcpld.c220
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c28
-rw-r--r--drivers/infiniband/Kconfig1
-rw-r--r--drivers/infiniband/core/agent.c1
-rw-r--r--drivers/infiniband/core/cache.c16
-rw-r--r--drivers/infiniband/core/cm.c72
-rw-r--r--drivers/infiniband/core/cma.c43
-rw-r--r--drivers/infiniband/core/core_priv.h3
-rw-r--r--drivers/infiniband/core/device.c5
-rw-r--r--drivers/infiniband/core/fmr_pool.c1
-rw-r--r--drivers/infiniband/core/iwcm.c21
-rw-r--r--drivers/infiniband/core/iwpm_msg.c1
-rw-r--r--drivers/infiniband/core/iwpm_util.c12
-rw-r--r--drivers/infiniband/core/mad.c46
-rw-r--r--drivers/infiniband/core/multicast.c7
-rw-r--r--drivers/infiniband/core/roce_gid_mgmt.c21
-rw-r--r--drivers/infiniband/core/ucm.c5
-rw-r--r--drivers/infiniband/core/ucma.c5
-rw-r--r--drivers/infiniband/core/umem.c2
-rw-r--r--drivers/infiniband/core/uverbs.h1
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c229
-rw-r--r--drivers/infiniband/core/uverbs_main.c6
-rw-r--r--drivers/infiniband/core/verbs.c108
-rw-r--r--drivers/infiniband/hw/Makefile1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_dbg.c20
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c3
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c8
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c4
-rw-r--r--drivers/infiniband/hw/hfi1/affinity.c3
-rw-r--r--drivers/infiniband/hw/hfi1/affinity.h9
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c9
-rw-r--r--drivers/infiniband/hw/hfi1/chip_registers.h3
-rw-r--r--drivers/infiniband/hw/hfi1/debugfs.c110
-rw-r--r--drivers/infiniband/hw/hfi1/driver.c3
-rw-r--r--drivers/infiniband/hw/hfi1/eprom.c211
-rw-r--r--drivers/infiniband/hw/hfi1/firmware.c156
-rw-r--r--drivers/infiniband/hw/hfi1/hfi.h144
-rw-r--r--drivers/infiniband/hw/hfi1/iowait.h8
-rw-r--r--drivers/infiniband/hw/hfi1/mad.c31
-rw-r--r--drivers/infiniband/hw/hfi1/mmu_rb.c2
-rw-r--r--drivers/infiniband/hw/hfi1/pio.c40
-rw-r--r--drivers/infiniband/hw/hfi1/pio.h38
-rw-r--r--drivers/infiniband/hw/hfi1/pio_copy.c22
-rw-r--r--drivers/infiniband/hw/hfi1/platform.c193
-rw-r--r--drivers/infiniband/hw/hfi1/platform.h127
-rw-r--r--drivers/infiniband/hw/hfi1/qp.c11
-rw-r--r--drivers/infiniband/hw/hfi1/rc.c60
-rw-r--r--drivers/infiniband/hw/hfi1/ruc.c44
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.c18
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.h12
-rw-r--r--drivers/infiniband/hw/hfi1/uc.c4
-rw-r--r--drivers/infiniband/hw/hfi1/ud.c4
-rw-r--r--drivers/infiniband/hw/hfi1/user_sdma.c60
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.c209
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.h16
-rw-r--r--drivers/infiniband/hw/hfi1/verbs_txreq.c13
-rw-r--r--drivers/infiniband/hw/hfi1/verbs_txreq.h1
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_ah.c3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_alloc.c11
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cmd.c8
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cmd.h12
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_common.h44
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cq.c46
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_device.h66
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_eq.c6
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hem.c6
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.c1222
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.h74
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_main.c329
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_mr.c43
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_pd.c5
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_qp.c4
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw.h37
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_cm.c377
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_cm.h11
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_ctrl.c646
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_d.h25
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_hw.c61
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_main.c166
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_osdep.h8
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_p.h21
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_pble.c4
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_puda.c271
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_puda.h20
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_type.h98
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_uk.c40
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_user.h14
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_utils.c289
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.c238
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.h2
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_virtchnl.c33
-rw-r--r--drivers/infiniband/hw/mlx4/ah.c10
-rw-r--r--drivers/infiniband/hw/mlx4/alias_GUID.c4
-rw-r--r--drivers/infiniband/hw/mlx4/cm.c4
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c58
-rw-r--r--drivers/infiniband/hw/mlx4/main.c49
-rw-r--r--drivers/infiniband/hw/mlx4/mcg.c5
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h3
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c13
-rw-r--r--drivers/infiniband/hw/mlx5/ah.c25
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c34
-rw-r--r--drivers/infiniband/hw/mlx5/main.c268
-rw-r--r--drivers/infiniband/hw/mlx5/mem.c7
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h12
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c71
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c131
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c4
-rw-r--r--drivers/infiniband/hw/nes/nes.c1
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c4
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c6
-rw-r--r--drivers/infiniband/hw/nes/nes_mgt.c10
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c84
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c7
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_ah.c3
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_ah.h4
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_hw.c7
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_stats.c4
-rw-r--r--drivers/infiniband/hw/qedr/verbs.c27
-rw-r--r--drivers/infiniband/hw/qedr/verbs.h3
-rw-r--r--drivers/infiniband/hw/qib/qib_diag.c6
-rw-r--r--drivers/infiniband/hw/qib/qib_driver.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_eeprom.c6
-rw-r--r--drivers/infiniband/hw/qib/qib_file_ops.c5
-rw-r--r--drivers/infiniband/hw/qib/qib_iba6120.c8
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c8
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c22
-rw-r--r--drivers/infiniband/hw/qib/qib_init.c47
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c44
-rw-r--r--drivers/infiniband/hw/qib/qib_ruc.c24
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.c33
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c22
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.c16
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.h4
-rw-r--r--drivers/infiniband/hw/usnic/usnic_vnic.c22
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/Kconfig7
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/Makefile3
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma.h474
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_cmd.c119
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c425
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h586
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_doorbell.c127
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c1211
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c304
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c334
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c972
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h131
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c579
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h436
-rw-r--r--drivers/infiniband/sw/rdmavt/cq.c63
-rw-r--r--drivers/infiniband/sw/rdmavt/mcast.c5
-rw-r--r--drivers/infiniband/sw/rdmavt/mr.c22
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c20
-rw-r--r--drivers/infiniband/sw/rdmavt/trace.h141
-rw-r--r--drivers/infiniband/sw/rdmavt/trace_mr.h112
-rw-r--r--drivers/infiniband/sw/rdmavt/trace_qp.h96
-rw-r--r--drivers/infiniband/sw/rdmavt/trace_rvt.h81
-rw-r--r--drivers/infiniband/sw/rdmavt/trace_tx.h132
-rw-r--r--drivers/infiniband/sw/rxe/rxe_comp.c9
-rw-r--r--drivers/infiniband/sw/rxe/rxe_loc.h2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mr.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_net.c8
-rw-r--r--drivers/infiniband/sw/rxe/rxe_param.h2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_pool.c1
-rw-r--r--drivers/infiniband/sw/rxe/rxe_recv.c11
-rw-r--r--drivers/infiniband/sw/rxe/rxe_req.c20
-rw-r--r--drivers/infiniband/sw/rxe/rxe_resp.c25
-rw-r--r--drivers/infiniband/sw/rxe/rxe_srq.c2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_task.c19
-rw-r--r--drivers/infiniband/sw/rxe/rxe_task.h1
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.c21
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c10
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c5
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c5
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c7
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c5
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c31
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c48
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c22
-rw-r--r--drivers/iommu/amd_iommu.c2
-rw-r--r--drivers/iommu/amd_iommu_init.c4
-rw-r--r--drivers/iommu/amd_iommu_v2.c4
-rw-r--r--drivers/iommu/arm-smmu-v3.c104
-rw-r--r--drivers/iommu/arm-smmu.c177
-rw-r--r--drivers/iommu/dma-iommu.c24
-rw-r--r--drivers/iommu/exynos-iommu.c293
-rw-r--r--drivers/iommu/io-pgtable-arm-v7s.c5
-rw-r--r--drivers/iommu/io-pgtable-arm.c7
-rw-r--r--drivers/iommu/iommu.c53
-rw-r--r--drivers/iommu/iova.c2
-rw-r--r--drivers/iommu/mtk_iommu.c85
-rw-r--r--drivers/iommu/mtk_iommu.h11
-rw-r--r--drivers/iommu/mtk_iommu_v1.c105
-rw-r--r--drivers/iommu/of_iommu.c39
-rw-r--r--drivers/iommu/s390-iommu.c1
-rw-r--r--drivers/mailbox/Kconfig9
-rw-r--r--drivers/mailbox/Makefile2
-rw-r--r--drivers/mailbox/tegra-hsp.c479
-rw-r--r--drivers/memory/Kconfig8
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/atmel-ebi.c2
-rw-r--r--drivers/memory/atmel-sdramc.c6
-rw-r--r--drivers/memory/da8xx-ddrctl.c173
-rw-r--r--drivers/mfd/88pm860x-core.c5
-rw-r--r--drivers/misc/sram.c42
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c84
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_roce.c4
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h3
-rw-r--r--drivers/nvme/host/rdma.c42
-rw-r--r--drivers/nvme/target/rdma.c3
-rw-r--r--drivers/of/base.c9
-rw-r--r--drivers/of/irq.c1
-rw-r--r--drivers/of/of_numa.c7
-rw-r--r--drivers/of/of_pci.c21
-rw-r--r--drivers/of/platform.c6
-rw-r--r--drivers/of/resolver.c358
-rw-r--r--drivers/pci/access.c16
-rw-r--r--drivers/pci/bus.c2
-rw-r--r--drivers/pci/ecam.c12
-rw-r--r--drivers/pci/host/Kconfig16
-rw-r--r--drivers/pci/host/Makefile19
-rw-r--r--drivers/pci/host/pci-hyperv.c100
-rw-r--r--drivers/pci/host/pci-layerscape.c20
-rw-r--r--drivers/pci/host/pci-rcar-gen2.c2
-rw-r--r--drivers/pci/host/pci-tegra.c160
-rw-r--r--drivers/pci/host/pci-thunder-ecam.c9
-rw-r--r--drivers/pci/host/pci-thunder-pem.c94
-rw-r--r--drivers/pci/host/pci-xgene.c126
-rw-r--r--drivers/pci/host/pcie-altera.c10
-rw-r--r--drivers/pci/host/pcie-hisi.c107
-rw-r--r--drivers/pci/host/pcie-iproc-bcma.c1
-rw-r--r--drivers/pci/host/pcie-iproc-msi.c1
-rw-r--r--drivers/pci/host/pcie-iproc-platform.c28
-rw-r--r--drivers/pci/host/pcie-iproc.c949
-rw-r--r--drivers/pci/host/pcie-iproc.h45
-rw-r--r--drivers/pci/host/pcie-qcom.c177
-rw-r--r--drivers/pci/host/pcie-rcar.c5
-rw-r--r--drivers/pci/host/pcie-rockchip.c284
-rw-r--r--drivers/pci/host/pcie-spear13xx.c6
-rw-r--r--drivers/pci/host/vmd.c30
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c31
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c3
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c10
-rw-r--r--drivers/pci/hotplug/pciehp_core.c9
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c8
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c21
-rw-r--r--drivers/pci/iov.c70
-rw-r--r--drivers/pci/msi.c3
-rw-r--r--drivers/pci/pci-acpi.c100
-rw-r--r--drivers/pci/pci-mid.c2
-rw-r--r--drivers/pci/pci-sysfs.c2
-rw-r--r--drivers/pci/pci.c138
-rw-r--r--drivers/pci/pci.h19
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c18
-rw-r--r--drivers/pci/pcie/aspm.c22
-rw-r--r--drivers/pci/pcie/pme.c29
-rw-r--r--drivers/pci/pcie/portdrv_core.c3
-rw-r--r--drivers/pci/pcie/portdrv_pci.c13
-rw-r--r--drivers/pci/probe.c248
-rw-r--r--drivers/pci/quirks.c182
-rw-r--r--drivers/pci/remove.c2
-rw-r--r--drivers/pci/rom.c5
-rw-r--r--drivers/pci/setup-res.c48
-rw-r--r--drivers/pinctrl/bcm/pinctrl-bcm2835.c6
-rw-r--r--drivers/platform/x86/Kconfig11
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c56
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c23
-rw-r--r--drivers/platform/x86/asus-wmi.c29
-rw-r--r--drivers/platform/x86/asus-wmi.h1
-rw-r--r--drivers/platform/x86/dell-laptop.c26
-rw-r--r--drivers/platform/x86/dell-wmi.c12
-rw-r--r--drivers/platform/x86/intel-hid.c6
-rw-r--r--drivers/platform/x86/intel-smartconnect.c2
-rw-r--r--drivers/platform/x86/intel-vbtn.c35
-rw-r--r--drivers/platform/x86/intel_mid_thermal.c2
-rw-r--r--drivers/platform/x86/intel_pmc_core.c386
-rw-r--r--drivers/platform/x86/intel_pmc_core.h110
-rw-r--r--drivers/platform/x86/mlxcpld-hotplug.c515
-rw-r--r--drivers/platform/x86/panasonic-laptop.c2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c95
-rw-r--r--drivers/pwm/Kconfig9
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/pwm-hibvt.c271
-rw-r--r--drivers/pwm/pwm-meson.c1
-rw-r--r--drivers/reset/Kconfig1
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/core.c43
-rw-r--r--drivers/reset/reset-berlin.c12
-rw-r--r--drivers/reset/reset-lpc18xx.c32
-rw-r--r--drivers/reset/reset-oxnas.c1
-rw-r--r--drivers/reset/reset-socfpga.c10
-rw-r--r--drivers/reset/reset-sunxi.c9
-rw-r--r--drivers/reset/reset-zynq.c10
-rw-r--r--drivers/reset/sti/Kconfig8
-rw-r--r--drivers/reset/sti/Makefile2
-rw-r--r--drivers/reset/sti/reset-stih415.c112
-rw-r--r--drivers/reset/sti/reset-stih416.c143
-rw-r--r--drivers/reset/tegra/Kconfig2
-rw-r--r--drivers/reset/tegra/Makefile1
-rw-r--r--drivers/reset/tegra/reset-bpmp.c71
-rw-r--r--drivers/soc/mediatek/Kconfig2
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c465
-rw-r--r--drivers/soc/renesas/Makefile4
-rw-r--r--drivers/soc/renesas/r8a7743-sysc.c32
-rw-r--r--drivers/soc/renesas/r8a7745-sysc.c32
-rw-r--r--drivers/soc/renesas/rcar-sysc.c6
-rw-r--r--drivers/soc/renesas/rcar-sysc.h2
-rw-r--r--drivers/soc/renesas/renesas-soc.c257
-rw-r--r--drivers/soc/rockchip/pm_domains.c81
-rw-r--r--drivers/soc/tegra/Kconfig14
-rw-r--r--drivers/soc/tegra/pmc.c398
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c2
-rw-r--r--drivers/spi/spi-s3c64xx.c21
-rw-r--r--drivers/tty/serial/8250/8250_lpss.c2
-rw-r--r--drivers/usb/host/uhci-pci.c4
-rw-r--r--drivers/vfio/pci/vfio_pci_config.c2
-rw-r--r--drivers/watchdog/sa1100_wdt.c24
-rw-r--r--fs/direct-io.c2
-rw-r--r--fs/internal.h3
-rw-r--r--fs/iomap.c373
-rw-r--r--fs/orangefs/orangefs-debugfs.c4
-rw-r--r--fs/orangefs/orangefs-sysfs.c9
-rw-r--r--fs/ubifs/Kconfig11
-rw-r--r--fs/ubifs/Makefile1
-rw-r--r--fs/ubifs/crypto.c97
-rw-r--r--fs/ubifs/debug.c14
-rw-r--r--fs/ubifs/dir.c478
-rw-r--r--fs/ubifs/file.c108
-rw-r--r--fs/ubifs/gc.c4
-rw-r--r--fs/ubifs/io.c18
-rw-r--r--fs/ubifs/ioctl.c20
-rw-r--r--fs/ubifs/journal.c224
-rw-r--r--fs/ubifs/key.h21
-rw-r--r--fs/ubifs/replay.c10
-rw-r--r--fs/ubifs/sb.c59
-rw-r--r--fs/ubifs/super.c17
-rw-r--r--fs/ubifs/tnc.c159
-rw-r--r--fs/ubifs/ubifs-media.h29
-rw-r--r--fs/ubifs/ubifs.h115
-rw-r--r--fs/ubifs/xattr.c116
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c10
-rw-r--r--fs/xfs/libxfs/xfs_alloc_btree.c6
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c8
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.h4
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c336
-rw-r--r--fs/xfs/libxfs/xfs_bmap.h9
-rw-r--r--fs/xfs/libxfs/xfs_bmap_btree.c3
-rw-r--r--fs/xfs/libxfs/xfs_btree.c20
-rw-r--r--fs/xfs/libxfs/xfs_btree.h43
-rw-r--r--fs/xfs/libxfs/xfs_cksum.h26
-rw-r--r--fs/xfs/libxfs/xfs_dir2.c2
-rw-r--r--fs/xfs/libxfs/xfs_dir2.h5
-rw-r--r--fs/xfs/libxfs/xfs_dir2_data.c26
-rw-r--r--fs/xfs/libxfs/xfs_dir2_priv.h1
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c18
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c4
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c16
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.h4
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c77
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.h7
-rw-r--r--fs/xfs/libxfs/xfs_log_format.h4
-rw-r--r--fs/xfs/libxfs/xfs_log_recover.h2
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.c1
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.c1
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.c1
-rw-r--r--fs/xfs/libxfs/xfs_sb.c13
-rw-r--r--fs/xfs/libxfs/xfs_types.h4
-rw-r--r--fs/xfs/xfs_aops.c286
-rw-r--r--fs/xfs/xfs_aops.h6
-rw-r--r--fs/xfs/xfs_attr.h4
-rw-r--r--fs/xfs/xfs_attr_list.c59
-rw-r--r--fs/xfs/xfs_bmap_util.c45
-rw-r--r--fs/xfs/xfs_buf.c123
-rw-r--r--fs/xfs/xfs_buf.h3
-rw-r--r--fs/xfs/xfs_dir2_readdir.c2
-rw-r--r--fs/xfs/xfs_file.c264
-rw-r--r--fs/xfs/xfs_icache.c40
-rw-r--r--fs/xfs/xfs_icreate_item.c2
-rw-r--r--fs/xfs/xfs_inode.c84
-rw-r--r--fs/xfs/xfs_inode.h18
-rw-r--r--fs/xfs/xfs_inode_item.c4
-rw-r--r--fs/xfs/xfs_ioctl.c8
-rw-r--r--fs/xfs/xfs_iomap.c104
-rw-r--r--fs/xfs/xfs_iops.c14
-rw-r--r--fs/xfs/xfs_linux.h1
-rw-r--r--fs/xfs/xfs_log.c41
-rw-r--r--fs/xfs/xfs_log_recover.c16
-rw-r--r--fs/xfs/xfs_mount.c7
-rw-r--r--fs/xfs/xfs_mount.h7
-rw-r--r--fs/xfs/xfs_pnfs.c7
-rw-r--r--fs/xfs/xfs_pnfs.h4
-rw-r--r--fs/xfs/xfs_qm.c2
-rw-r--r--fs/xfs/xfs_reflink.c191
-rw-r--r--fs/xfs/xfs_reflink.h6
-rw-r--r--fs/xfs/xfs_stats.c10
-rw-r--r--fs/xfs/xfs_stats.h200
-rw-r--r--fs/xfs/xfs_super.c27
-rw-r--r--fs/xfs/xfs_symlink.c7
-rw-r--r--fs/xfs/xfs_trace.h109
-rw-r--r--fs/xfs/xfs_xattr.c23
-rw-r--r--include/acpi/acpi_bus.h2
-rw-r--r--include/asm-generic/vmlinux.lds.h1
-rw-r--r--include/clocksource/pxa.h3
-rw-r--r--include/dt-bindings/clock/r7s72100-clock.h7
-rw-r--r--include/dt-bindings/clock/r8a7794-clock.h3
-rw-r--r--include/dt-bindings/clock/stih415-clks.h16
-rw-r--r--include/dt-bindings/clock/tegra186-clock.h940
-rw-r--r--include/dt-bindings/mailbox/tegra186-hsp.h24
-rw-r--r--include/dt-bindings/mfd/tps65217.h26
-rw-r--r--include/dt-bindings/pinctrl/bcm2835.h5
-rw-r--r--include/dt-bindings/pinctrl/qcom,pmic-gpio.h4
-rw-r--r--include/dt-bindings/pinctrl/qcom,pmic-mpp.h6
-rw-r--r--include/dt-bindings/pinctrl/rockchip.h33
-rw-r--r--include/dt-bindings/power/mt2701-power.h27
-rw-r--r--include/dt-bindings/power/r8a7743-sysc.h25
-rw-r--r--include/dt-bindings/power/r8a7745-sysc.h25
-rw-r--r--include/dt-bindings/power/tegra186-powergate.h39
-rw-r--r--include/dt-bindings/reset/oxsemi,ox810se.h53
-rw-r--r--include/dt-bindings/reset/oxsemi,ox820.h53
-rw-r--r--include/dt-bindings/reset/tegra186-reset.h217
-rw-r--r--include/linux/acpi.h33
-rw-r--r--include/linux/acpi_iort.h16
-rw-r--r--include/linux/amba/pl08x.h4
-rw-r--r--include/linux/dma-iommu.h4
-rw-r--r--include/linux/dmaengine.h8
-rw-r--r--include/linux/ftrace.h4
-rw-r--r--include/linux/fwnode.h3
-rw-r--r--include/linux/i2c-smbus.h27
-rw-r--r--include/linux/i2c.h26
-rw-r--r--include/linux/i2c/mlxcpld.h52
-rw-r--r--include/linux/init.h3
-rw-r--r--include/linux/iomap.h11
-rw-r--r--include/linux/iommu.h15
-rw-r--r--include/linux/kernel.h9
-rw-r--r--include/linux/lockdep.h25
-rw-r--r--include/linux/mfd/tps65217.h11
-rw-r--r--include/linux/mlx5/mlx5_ifc.h2
-rw-r--r--include/linux/module.h4
-rw-r--r--include/linux/of_iommu.h12
-rw-r--r--include/linux/of_pci.h7
-rw-r--r--include/linux/pci-acpi.h4
-rw-r--r--include/linux/pci-ecam.h9
-rw-r--r--include/linux/pci.h17
-rw-r--r--include/linux/pci_hotplug.h2
-rw-r--r--include/linux/pci_ids.h28
-rw-r--r--include/linux/platform_data/dma-dw.h5
-rw-r--r--include/linux/platform_data/mlxcpld-hotplug.h99
-rw-r--r--include/linux/platform_data/spi-s3c64xx.h3
-rw-r--r--include/linux/platform_data/usb-davinci.h23
-rw-r--r--include/linux/soc/qcom/wcnss_ctrl.h13
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h249
-rw-r--r--include/linux/stm.h4
-rw-r--r--include/linux/trace.h28
-rw-r--r--include/linux/tracepoint-defs.h2
-rw-r--r--include/linux/tracepoint.h2
-rw-r--r--include/rdma/ib_cm.h6
-rw-r--r--include/rdma/ib_mad.h2
-rw-r--r--include/rdma/ib_verbs.h70
-rw-r--r--include/rdma/iw_cm.h6
-rw-r--r--include/rdma/opa_smi.h2
-rw-r--r--include/rdma/rdma_cm.h25
-rw-r--r--include/rdma/rdma_vt.h46
-rw-r--r--include/rdma/rdmavt_mr.h10
-rw-r--r--include/rdma/rdmavt_qp.h77
-rw-r--r--include/soc/arc/aux.h63
-rw-r--r--include/soc/arc/mcip.h (renamed from arch/arc/include/asm/mcip.h)10
-rw-r--r--include/soc/arc/timers.h38
-rw-r--r--include/soc/at91/atmel-secumod.h19
-rw-r--r--include/soc/nps/mtm.h59
-rw-r--r--include/soc/tegra/bpmp-abi.h1601
-rw-r--r--include/soc/tegra/bpmp.h141
-rw-r--r--include/soc/tegra/ivc.h109
-rw-r--r--include/soc/tegra/pmc.h126
-rw-r--r--include/trace/events/i2c.h2
-rw-r--r--include/uapi/linux/pci_regs.h8
-rw-r--r--include/uapi/rdma/Kbuild2
-rw-r--r--include/uapi/rdma/hfi/hfi1_user.h2
-rw-r--r--include/uapi/rdma/hns-abi.h (renamed from drivers/infiniband/hw/hns/hns_roce_user.h)9
-rw-r--r--include/uapi/rdma/ib_user_verbs.h38
-rw-r--r--include/uapi/rdma/mlx5-abi.h38
-rw-r--r--include/uapi/rdma/rdma_user_cm.h12
-rw-r--r--include/uapi/rdma/vmw_pvrdma-abi.h289
-rw-r--r--init/main.c7
-rw-r--r--kernel/locking/lockdep.c20
-rw-r--r--kernel/module.c69
-rw-r--r--kernel/panic.c53
-rw-r--r--kernel/printk/printk.c221
-rw-r--r--kernel/sysctl.c2
-rw-r--r--kernel/trace/Kconfig2
-rw-r--r--kernel/trace/ftrace.c4
-rw-r--r--kernel/trace/ring_buffer.c28
-rw-r--r--kernel/trace/trace.c485
-rw-r--r--kernel/trace/trace.h19
-rw-r--r--kernel/trace/trace_benchmark.c26
-rw-r--r--kernel/trace/trace_benchmark.h2
-rw-r--r--kernel/trace/trace_branch.c2
-rw-r--r--kernel/trace/trace_entries.h15
-rw-r--r--kernel/trace/trace_events.c83
-rw-r--r--kernel/trace/trace_events_filter.c119
-rw-r--r--kernel/trace/trace_functions_graph.c35
-rw-r--r--kernel/trace/trace_hwlat.c2
-rw-r--r--kernel/trace/trace_irqsoff.c12
-rw-r--r--kernel/trace/trace_kprobe.c47
-rw-r--r--kernel/trace/trace_output.c30
-rw-r--r--kernel/trace/trace_sched_wakeup.c13
-rw-r--r--kernel/tracepoint.c12
-rw-r--r--lib/radix-tree.c1
-rw-r--r--net/rds/rdma_transport.c5
-rw-r--r--samples/trace_events/trace-events-sample.c3
-rw-r--r--samples/trace_events/trace-events-sample.h2
-rw-r--r--scripts/mod/modpost.c2
-rw-r--r--scripts/recordmcount.c65
-rw-r--r--scripts/sign-file.c2
-rw-r--r--tools/testing/radix-tree/linux/cpu.h22
-rw-r--r--tools/testing/radix-tree/linux/notifier.h8
-rw-r--r--tools/testing/selftests/.gitignore1
-rw-r--r--tools/testing/selftests/Makefile2
-rwxr-xr-xtools/testing/selftests/drivers/gpu/i915.sh14
-rw-r--r--tools/testing/selftests/ftrace/.gitignore1
-rwxr-xr-xtools/testing/selftests/ftrace/ftracetest16
-rw-r--r--tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc49
-rw-r--r--tools/testing/selftests/ftrace/test.d/functions28
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc37
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc2
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc5
-rw-r--r--tools/testing/selftests/gpio/Makefile23
-rw-r--r--tools/testing/selftests/gpio/gpio-mockup-chardev.c324
-rwxr-xr-xtools/testing/selftests/gpio/gpio-mockup-sysfs.sh134
-rwxr-xr-xtools/testing/selftests/gpio/gpio-mockup.sh201
-rw-r--r--tools/testing/selftests/nsfs/.gitignore2
-rw-r--r--tools/testing/selftests/sigaltstack/.gitignore1
-rw-r--r--tools/testing/selftests/sync/.gitignore1
-rw-r--r--tools/testing/selftests/sync/Makefile24
-rw-r--r--tools/testing/selftests/sync/sw_sync.h46
-rw-r--r--tools/testing/selftests/sync/sync.c221
-rw-r--r--tools/testing/selftests/sync/sync.h40
-rw-r--r--tools/testing/selftests/sync/sync_alloc.c74
-rw-r--r--tools/testing/selftests/sync/sync_fence.c132
-rw-r--r--tools/testing/selftests/sync/sync_merge.c60
-rw-r--r--tools/testing/selftests/sync/sync_stress_consumer.c185
-rw-r--r--tools/testing/selftests/sync/sync_stress_merge.c115
-rw-r--r--tools/testing/selftests/sync/sync_stress_parallelism.c111
-rw-r--r--tools/testing/selftests/sync/sync_test.c79
-rw-r--r--tools/testing/selftests/sync/sync_wait.c91
-rw-r--r--tools/testing/selftests/sync/synctest.h66
-rw-r--r--tools/testing/selftests/timers/.gitignore1
1449 files changed, 73319 insertions, 29262 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index b3bc50f650ee..5a1732b78707 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -294,3 +294,10 @@ Description:
a firmware bug to the system vendor. Writing to this file
taints the kernel with TAINT_FIRMWARE_WORKAROUND, which
reduces the supportability of your system.
+
+What: /sys/bus/pci/devices/.../revision
+Date: November 2016
+Contact: Emil Velikov <emil.l.velikov@gmail.com>
+Description:
+ This file contains the revision field of the the PCI device.
+ The value comes from device config space. The file is read only.
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index c0d8788e75d3..72292308d0f5 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -111,6 +111,8 @@ ipmi_ssif - A driver for accessing BMCs on the SMBus. It uses the
I2C kernel driver's SMBus interfaces to send and receive IPMI messages
over the SMBus.
+ipmi_powernv - A driver for access BMCs on POWERNV systems.
+
ipmi_watchdog - IPMI requires systems to have a very capable watchdog
timer. This driver implements the standard Linux watchdog timer
interface on top of the IPMI message handler.
@@ -118,17 +120,15 @@ interface on top of the IPMI message handler.
ipmi_poweroff - Some systems support the ability to be turned off via
IPMI commands.
-These are all individually selectable via configuration options.
+bt-bmc - This is not part of the main driver, but instead a driver for
+accessing a BMC-side interface of a BT interface. It is used on BMCs
+running Linux to provide an interface to the host.
-Note that the KCS-only interface has been removed. The af_ipmi driver
-is no longer supported and has been removed because it was impossible
-to do 32 bit emulation on 64-bit kernels with it.
+These are all individually selectable via configuration options.
Much documentation for the interface is in the include files. The
IPMI include files are:
-net/af_ipmi.h - Contains the socket interface.
-
linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
linux/ipmi_smi.h - Contains the interface for system management interfaces
@@ -245,6 +245,16 @@ addressed (because some boards actually have multiple BMCs on them)
and the user should not have to care what type of SMI is below them.
+Watching For Interfaces
+
+When your code comes up, the IPMI driver may or may not have detected
+if IPMI devices exist. So you might have to defer your setup until
+the device is detected, or you might be able to do it immediately.
+To handle this, and to allow for discovery, you register an SMI
+watcher with ipmi_smi_watcher_register() to iterate over interfaces
+and tell you when they come and go.
+
+
Creating the User
To user the message handler, you must first create a user using
@@ -263,7 +273,7 @@ closing the device automatically destroys the user.
Messaging
-To send a message from kernel-land, the ipmi_request() call does
+To send a message from kernel-land, the ipmi_request_settime() call does
pretty much all message handling. Most of the parameter are
self-explanatory. However, it takes a "msgid" parameter. This is NOT
the sequence number of messages. It is simply a long value that is
@@ -352,11 +362,12 @@ that for more details.
The SI Driver
-------------
-The SI driver allows up to 4 KCS or SMIC interfaces to be configured
-in the system. By default, scan the ACPI tables for interfaces, and
-if it doesn't find any the driver will attempt to register one KCS
-interface at the spec-specified I/O port 0xca2 without interrupts.
-You can change this at module load time (for a module) with:
+The SI driver allows KCS, BT, and SMIC interfaces to be configured
+in the system. It discovers interfaces through a host of different
+methods, depending on the system.
+
+You can specify up to four interfaces on the module load line and
+control some module parameters:
modprobe ipmi_si.o type=<type1>,<type2>....
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
@@ -367,7 +378,7 @@ You can change this at module load time (for a module) with:
force_kipmid=<enable1>,<enable2>,...
kipmid_max_busy_us=<ustime1>,<ustime2>,...
unload_when_empty=[0|1]
- trydefaults=[0|1] trydmi=[0|1] tryacpi=[0|1]
+ trydmi=[0|1] tryacpi=[0|1]
tryplatform=[0|1] trypci=[0|1]
Each of these except try... items is a list, the first item for the
@@ -386,10 +397,6 @@ use the I/O port given as the device address.
If you specify irqs as non-zero for an interface, the driver will
attempt to use the given interrupt for the device.
-trydefaults sets whether the standard IPMI interface at 0xca2 and
-any interfaces specified by ACPE are tried. By default, the driver
-tries it, set this value to zero to turn this off.
-
The other try... items disable discovery by their corresponding
names. These are all enabled by default, set them to zero to disable
them. The tryplatform disables openfirmware.
@@ -434,7 +441,7 @@ kernel command line as:
ipmi_si.type=<type1>,<type2>...
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
- ipmi_si.irqs=<irq1>,<irq2>... ipmi_si.trydefaults=[0|1]
+ ipmi_si.irqs=<irq1>,<irq2>...
ipmi_si.regspacings=<sp1>,<sp2>,...
ipmi_si.regsizes=<size1>,<size2>,...
ipmi_si.regshifts=<shift1>,<shift2>,...
@@ -444,11 +451,6 @@ kernel command line as:
It works the same as the module parameters of the same names.
-By default, the driver will attempt to detect any device specified by
-ACPI, and if none of those then a KCS device at the spec-specified
-0xca2. If you want to turn this off, set the "trydefaults" option to
-false.
-
If your IPMI interface does not support interrupts and is a KCS or
SMIC interface, the IPMI driver will start a kernel thread for the
interface to help speed things up. This is a low-priority kernel
@@ -500,7 +502,8 @@ at module load time (for a module) with:
addr=<i2caddr1>[,<i2caddr2>[,...]]
adapter=<adapter1>[,<adapter2>[...]]
dbg=<flags1>,<flags2>...
- slave_addrs=<addr1>,<addr2>,...
+ slave_addrs=<addr1>,<addr2>,...
+ tryacpi=[0|1] trydmi=[0|1]
[dbg_probe=1]
The addresses are normal I2C addresses. The adapter is the string
@@ -513,6 +516,9 @@ spaces in kernel parameters.
The debug flags are bit flags for each BMC found, they are:
IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
+The tryxxx parameters can be used to disable detecting interfaces
+from various sources.
+
Setting dbg_probe to 1 will enable debugging of the probing and
detection process for BMCs on the SMBusses.
@@ -535,7 +541,8 @@ kernel command line as:
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
ipmi_ssif.dbg=<flags1>[,<flags2>[...]]
ipmi_ssif.dbg_probe=1
- ipmi_ssif.slave_addrs=<addr1>[,<addr2>[...]]
+ ipmi_ssif.slave_addrs=<addr1>[,<addr2>[...]]
+ ipmi_ssif.tryacpi=[0|1] ipmi_ssif.trydmi=[0|1]
These are the same options as on the module command line.
diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
index 09aed5588d7c..a03b0357c017 100644
--- a/Documentation/arm/stm32/overview.txt
+++ b/Documentation/arm/stm32/overview.txt
@@ -5,7 +5,8 @@ Introduction
------------
The STMicroelectronics family of Cortex-M based MCUs are supported by the
- 'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
+ 'STM32' platform of ARM Linux. Currently only the STM32F429 (Cortex-M4)
+ and STM32F746 (Cortex-M7) are supported.
Configuration
diff --git a/Documentation/arm/stm32/stm32f746-overview.txt b/Documentation/arm/stm32/stm32f746-overview.txt
new file mode 100644
index 000000000000..cffd2b1ccd6f
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f746-overview.txt
@@ -0,0 +1,34 @@
+ STM32F746 Overview
+ ==================
+
+ Introduction
+ ------------
+ The STM32F746 is a Cortex-M7 MCU aimed at various applications.
+ It features:
+ - Cortex-M7 core running up to @216MHz
+ - 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
+ - FMC controller to connect SDRAM, NOR and NAND memories
+ - Dual mode QSPI
+ - SD/MMC/SDIO support
+ - Ethernet controller
+ - USB OTFG FS & HS controllers
+ - I2C, SPI, CAN busses support
+ - Several 16 & 32 bits general purpose timers
+ - Serial Audio interface
+ - LCD controller
+ - HDMI-CEC
+ - SPDIFRX
+
+ Resources
+ ---------
+ Datasheet and reference manual are publicly available on ST website:
+ - http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html
+
+ Document Author
+ ---------------
+ Alexandre Torgue <alexandre.torgue@st.com>
+
+
+
+
+
diff --git a/Documentation/devicetree/bindings/arm/amlogic,scpi.txt b/Documentation/devicetree/bindings/arm/amlogic,scpi.txt
new file mode 100644
index 000000000000..7b9a861e9306
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/amlogic,scpi.txt
@@ -0,0 +1,20 @@
+System Control and Power Interface (SCPI) Message Protocol
+(in addition to the standard binding in [0])
+----------------------------------------------------------
+Required properties
+
+- compatible : should be "amlogic,meson-gxbb-scpi"
+
+AMLOGIC SRAM and Shared Memory for SCPI
+------------------------------------
+
+Required properties:
+- compatible : should be "amlogic,meson-gxbb-sram"
+
+Each sub-node represents the reserved area for SCPI.
+
+Required sub-node properties:
+- compatible : should be "amlogic,meson-gxbb-scp-shmem" for SRAM based shared
+ memory on Amlogic GXBB SoC.
+
+[0] Documentation/devicetree/bindings/arm/arm,scpi.txt
diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt
index fcc6f6c10803..9b2b41ab6817 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.txt
+++ b/Documentation/devicetree/bindings/arm/amlogic.txt
@@ -17,6 +17,18 @@ Boards with the Amlogic Meson GXBaby SoC shall have the following properties:
Required root node property:
compatible: "amlogic,meson-gxbb";
+Boards with the Amlogic Meson GXL S905X SoC shall have the following properties:
+ Required root node property:
+ compatible: "amlogic,s905x", "amlogic,meson-gxl";
+
+Boards with the Amlogic Meson GXL S905D SoC shall have the following properties:
+ Required root node property:
+ compatible: "amlogic,s905d", "amlogic,meson-gxl";
+
+Boards with the Amlogic Meson GXM S912 SoC shall have the following properties:
+ Required root node property:
+ compatible: "amlogic,s912", "amlogic,meson-gxm";
+
Board compatible values:
- "geniatech,atv1200" (Meson6)
- "minix,neo-x8" (Meson8)
@@ -28,3 +40,10 @@ Board compatible values:
- "hardkernel,odroid-c2" (Meson gxbb)
- "amlogic,p200" (Meson gxbb)
- "amlogic,p201" (Meson gxbb)
+ - "amlogic,p212" (Meson gxl s905x)
+ - "amlogic,p230" (Meson gxl s905d)
+ - "amlogic,p231" (Meson gxl s905d)
+ - "amlogic,q200" (Meson gxm s912)
+ - "amlogic,q201" (Meson gxm s912)
+ - "nexbox,a95x" (Meson gxbb or Meson gxl s905x)
+ - "nexbox,a1" (Meson gxm s912)
diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt
index faa4b44572e3..401831973638 100644
--- a/Documentation/devicetree/bindings/arm/arm,scpi.txt
+++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt
@@ -7,7 +7,10 @@ by Linux to initiate various system control and power operations.
Required properties:
-- compatible : should be "arm,scpi"
+- compatible : should be
+ * "arm,scpi" : For implementations complying to SCPI v1.0 or above
+ * "arm,scpi-pre-1.0" : For implementations complying to all
+ unversioned releases prior to SCPI v1.0
- mboxes: List of phandle and mailbox channel specifiers
All the channels reserved by remote SCP firmware for use by
SCPI message protocol should be specified in any order
@@ -59,18 +62,14 @@ SRAM and Shared Memory for SCPI
A small area of SRAM is reserved for SCPI communication between application
processors and SCP.
-Required properties:
-- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno
-
-The rest of the properties should follow the generic mmio-sram description
-found in ../../sram/sram.txt
+The properties should follow the generic mmio-sram description found in [3]
Each sub-node represents the reserved area for SCPI.
Required sub-node properties:
- reg : The base offset and size of the reserved area with the SRAM
-- compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based
- shared memory on Juno platforms
+- compatible : should be "arm,scp-shmem" for Non-secure SRAM based
+ shared memory
Sensor bindings for the sensors based on SCPI Message Protocol
--------------------------------------------------------------
@@ -81,11 +80,9 @@ Required properties:
- #thermal-sensor-cells: should be set to 1. This property follows the
thermal device tree bindings[2].
- Valid cell values are raw identifiers (Sensor
- ID) as used by the firmware. Refer to
- platform documentation for your
- implementation for the IDs to use. For Juno
- R0 and Juno R1 refer to [3].
+ Valid cell values are raw identifiers (Sensor ID)
+ as used by the firmware. Refer to platform details
+ for your implementation for the IDs to use.
Power domain bindings for the power domains based on SCPI Message Protocol
------------------------------------------------------------
@@ -112,7 +109,7 @@ Required properties:
[0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/thermal/thermal.txt
-[3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html
+[3] Documentation/devicetree/bindings/sram/sram.txt
[4] Documentation/devicetree/bindings/power/power_domain.txt
Example:
diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards
index ab318a56fca2..b6e810c2781a 100644
--- a/Documentation/devicetree/bindings/arm/arm-boards
+++ b/Documentation/devicetree/bindings/arm/arm-boards
@@ -148,11 +148,12 @@ Example:
/dts-v1/;
#include <dt-bindings/interrupt-controller/irq.h>
-#include "skeleton.dtsi"
/ {
model = "ARM RealView PB1176 with device tree";
compatible = "arm,realview-pb1176";
+ #address-cells = <1>;
+ #size-cells = <1>;
soc {
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index e1f5ad855f14..29737b9b616e 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -225,3 +225,19 @@ required properties:
compatible = "atmel,sama5d3-sfr", "syscon";
reg = <0xf0038000 0x60>;
};
+
+Security Module (SECUMOD)
+
+The Security Module macrocell provides all necessary secure functions to avoid
+voltage, temperature, frequency and mechanical attacks on the chip. It also
+embeds secure memories that can be scrambled
+
+required properties:
+- compatible: Should be "atmel,<chip>-secumod", "syscon".
+ <chip> can be "sama5d2".
+- reg: Should contain registers location and length
+
+ secumod@fc040000 {
+ compatible = "atmel,sama5d2-secumod", "syscon";
+ reg = <0xfc040000 0x100>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/bcm/ns2.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,ns2.txt
index 35f056f4a1c3..35f056f4a1c3 100644
--- a/Documentation/devicetree/bindings/arm/bcm/ns2.txt
+++ b/Documentation/devicetree/bindings/arm/bcm/brcm,ns2.txt
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index c1dcf4cade2e..a1bcfeed5f24 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -178,6 +178,7 @@ nodes to be present and contain the properties described below.
"marvell,pj4b"
"marvell,sheeva-v5"
"nvidia,tegra132-denver"
+ "nvidia,tegra186-denver"
"qcom,krait"
"qcom,kryo"
"qcom,scorpion"
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index dbbc0952021c..d6ee9c6e1dbb 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -97,7 +97,7 @@ Freescale LS1021A Platform Device Tree Bindings
Required root node compatible properties:
- compatible = "fsl,ls1021a";
-Freescale LS1021A SoC-specific Device Tree Bindings
+Freescale SoC-specific Device Tree Bindings
-------------------------------------------
Freescale SCFG
@@ -105,7 +105,11 @@ Freescale SCFG
configuration and status registers for the chip. Such as getting PEX port
status.
Required properties:
- - compatible: should be "fsl,ls1021a-scfg"
+ - compatible: Should contain a chip-specific compatible string,
+ Chip-specific strings are of the form "fsl,<chip>-scfg",
+ The following <chip>s are known to be supported:
+ ls1021a, ls1043a, ls1046a, ls2080a.
+
- reg: should contain base address and length of SCFG memory-mapped registers
Example:
@@ -119,7 +123,11 @@ Freescale DCFG
configuration and status for the device. Such as setting the secondary
core start address and release the secondary core from holdoff and startup.
Required properties:
- - compatible: should be "fsl,ls1021a-dcfg"
+ - compatible: Should contain a chip-specific compatible string,
+ Chip-specific strings are of the form "fsl,<chip>-dcfg",
+ The following <chip>s are known to be supported:
+ ls1021a, ls1043a, ls1046a, ls2080a.
+
- reg : should contain base address and length of DCFG memory-mapped registers
Example:
@@ -131,6 +139,10 @@ Example:
Freescale ARMv8 based Layerscape SoC family Device Tree Bindings
----------------------------------------------------------------
+LS1043A SoC
+Required root node properties:
+ - compatible = "fsl,ls1043a";
+
LS1043A ARMv8 based RDB Board
Required root node properties:
- compatible = "fsl,ls1043a-rdb", "fsl,ls1043a";
@@ -139,6 +151,22 @@ LS1043A ARMv8 based QDS Board
Required root node properties:
- compatible = "fsl,ls1043a-qds", "fsl,ls1043a";
+LS1046A SoC
+Required root node properties:
+ - compatible = "fsl,ls1046a";
+
+LS1046A ARMv8 based QDS Board
+Required root node properties:
+ - compatible = "fsl,ls1046a-qds", "fsl,ls1046a";
+
+LS1046A ARMv8 based RDB Board
+Required root node properties:
+ - compatible = "fsl,ls1046a-rdb", "fsl,ls1046a";
+
+LS2080A SoC
+Required root node properties:
+ - compatible = "fsl,ls2080a";
+
LS2080A ARMv8 based Simulator model
Required root node properties:
- compatible = "fsl,ls2080a-simu", "fsl,ls2080a";
diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index 3f81575aa6be..7df79a715611 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -28,6 +28,10 @@ HiP06 D03 Board
Required root node properties:
- compatible = "hisilicon,hip06-d03";
+HiP07 D05 Board
+Required root node properties:
+ - compatible = "hisilicon,hip07-d05";
+
Hisilicon system controller
Required properties:
diff --git a/Documentation/devicetree/bindings/arm/juno,scpi.txt b/Documentation/devicetree/bindings/arm/juno,scpi.txt
new file mode 100644
index 000000000000..2ace8696bbee
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/juno,scpi.txt
@@ -0,0 +1,26 @@
+System Control and Power Interface (SCPI) Message Protocol
+(in addition to the standard binding in [0])
+
+Juno SRAM and Shared Memory for SCPI
+------------------------------------
+
+Required properties:
+- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM
+
+Each sub-node represents the reserved area for SCPI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based
+ shared memory on Juno platforms
+
+Sensor bindings for the sensors based on SCPI Message Protocol
+--------------------------------------------------------------
+Required properties:
+- compatible : should be "arm,scpi-sensors".
+- #thermal-sensor-cells: should be set to 1.
+ For Juno R0 and Juno R1 refer to [1] for the
+ sensor identifiers
+
+[0] Documentation/devicetree/bindings/arm/arm,scpi.txt
+[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html
diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
new file mode 100644
index 000000000000..31f5f9a104cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
@@ -0,0 +1,81 @@
+Texas Instruments System Control Interface (TI-SCI) Message Protocol
+--------------------------------------------------------------------
+
+Texas Instrument's processors including those belonging to Keystone generation
+of processors have separate hardware entity which is now responsible for the
+management of the System on Chip (SoC) system. These include various system
+level functions as well.
+
+An example of such an SoC is K2G, which contains the system control hardware
+block called Power Management Micro Controller (PMMC). This hardware block is
+initialized early into boot process and provides services to Operating Systems
+on multiple processors including ones running Linux.
+
+See http://processors.wiki.ti.com/index.php/TISCI for protocol definition.
+
+TI-SCI controller Device Node:
+=============================
+
+The TI-SCI node describes the Texas Instrument's System Controller entity node.
+This parent node may optionally have additional children nodes which describe
+specific functionality such as clocks, power domain, reset or additional
+functionality as may be required for the SoC. This hierarchy also describes the
+relationship between the TI-SCI parent node to the child node.
+
+Required properties:
+-------------------
+- compatible: should be "ti,k2g-sci"
+- mbox-names:
+ "rx" - Mailbox corresponding to receive path
+ "tx" - Mailbox corresponding to transmit path
+
+- mboxes: Mailboxes corresponding to the mbox-names. Each value of the mboxes
+ property should contain a phandle to the mailbox controller device
+ node and an args specifier that will be the phandle to the intended
+ sub-mailbox child node to be used for communication.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
+about the generic mailbox controller and client driver bindings. Also see
+Documentation/devicetree/bindings/mailbox/ti,message-manager.txt for typical
+controller that is used to communicate with this System controllers.
+
+Optional Properties:
+-------------------
+- reg-names:
+ debug_messages - Map the Debug message region
+- reg: register space corresponding to the debug_messages
+- ti,system-reboot-controller: If system reboot can be triggered by SoC reboot
+
+Example (K2G):
+-------------
+ pmmc: pmmc {
+ compatible = "ti,k2g-sci";
+ mbox-names = "rx", "tx";
+ mboxes= <&msgmgr &msgmgr_proxy_pmmc_rx>,
+ <&msgmgr &msgmgr_proxy_pmmc_tx>;
+ reg-names = "debug_messages";
+ reg = <0x02921800 0x800>;
+ };
+
+
+TI-SCI Client Device Node:
+=========================
+
+Client nodes are maintained as children of the relevant TI-SCI device node.
+
+Example (K2G):
+-------------
+ pmmc: pmmc {
+ compatible = "ti,k2g-sci";
+ ...
+
+ my_clk_node: clk_node {
+ ...
+ ...
+ };
+
+ my_pd_node: pd_node {
+ ...
+ ...
+ };
+ };
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
index f53e2ee65e35..05f95c3ed7d4 100644
--- a/Documentation/devicetree/bindings/arm/omap/omap.txt
+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -86,6 +86,9 @@ SoCs:
- DRA722
compatible = "ti,dra722", "ti,dra72", "ti,dra7"
+- DRA718
+ compatible = "ti,dra718", "ti,dra722", "ti,dra72", "ti,dra7"
+
- AM5728
compatible = "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7"
@@ -175,12 +178,18 @@ Boards:
- AM5728 IDK
compatible = "ti,am5728-idk", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7"
+- AM5718 IDK
+ compatible = "ti,am5718-idk", "ti,am5718", "ti,dra7"
+
- DRA742 EVM: Software Development Board for DRA742
compatible = "ti,dra7-evm", "ti,dra742", "ti,dra74", "ti,dra7"
- DRA722 EVM: Software Development Board for DRA722
compatible = "ti,dra72-evm", "ti,dra722", "ti,dra72", "ti,dra7"
+- DRA718 EVM: Software Development Board for DRA718
+ compatible = "ti,dra718-evm", "ti,dra718", "ti,dra722", "ti,dra72", "ti,dra7"
+
- DM3730 Logic PD Torpedo + Wireless: Commercial System on Module with WiFi and Bluetooth
compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3"
diff --git a/Documentation/devicetree/bindings/arm/oxnas.txt b/Documentation/devicetree/bindings/arm/oxnas.txt
index b9e49711ba05..ac64e60f99f1 100644
--- a/Documentation/devicetree/bindings/arm/oxnas.txt
+++ b/Documentation/devicetree/bindings/arm/oxnas.txt
@@ -5,5 +5,10 @@ Boards with the OX810SE SoC shall have the following properties:
Required root node property:
compatible: "oxsemi,ox810se"
+Boards with the OX820 SoC shall have the following properties:
+ Required root node property:
+ compatible: "oxsemi,ox820"
+
Board compatible values:
- "wd,mbwe" (OX810SE)
+ - "cloudengines,pogoplugv3" (OX820)
diff --git a/Documentation/devicetree/bindings/arm/qcom.txt b/Documentation/devicetree/bindings/arm/qcom.txt
index 3e24518c6678..028d16e72186 100644
--- a/Documentation/devicetree/bindings/arm/qcom.txt
+++ b/Documentation/devicetree/bindings/arm/qcom.txt
@@ -21,7 +21,10 @@ The 'SoC' element must be one of the following strings:
apq8096
msm8916
msm8974
+ msm8992
+ msm8994
msm8996
+ mdm9615
The 'board' element must be one of the following strings:
diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index 55f388f954de..cc4ace6397ab 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -25,6 +25,10 @@ Rockchip platforms device tree bindings
Required root node properties:
- compatible = "radxa,rock2-square", "rockchip,rk3288";
+- Rikomagic MK808 v1 board:
+ Required root node properties:
+ - compatible = "rikomagic,mk808", "rockchip,rk3066a";
+
- Firefly Firefly-RK3288 board:
Required root node properties:
- compatible = "firefly,firefly-rk3288", "rockchip,rk3288";
@@ -99,6 +103,18 @@ Rockchip platforms device tree bindings
Required root node properties:
- compatible = "mqmaker,miqi", "rockchip,rk3288";
+- Rockchip PX3 Evaluation board:
+ Required root node properties:
+ - compatible = "rockchip,px3-evb", "rockchip,px3", "rockchip,rk3188";
+
+- Rockchip PX5 Evaluation board:
+ Required root node properties:
+ - compatible = "rockchip,px5-evb", "rockchip,px5", "rockchip,rk3368";
+
+- Rockchip RK1108 Evaluation board
+ Required root node properties:
+ - compatible = "rockchip,rk1108-evb", "rockchip,rk1108";
+
- Rockchip RK3368 evb:
Required root node properties:
- compatible = "rockchip,rk3368-evb-act8846", "rockchip,rk3368";
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
index 0ea7f14ef294..3c551894f621 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
@@ -15,6 +15,8 @@ Required root node properties:
- "samsung,xyref5260" - for Exynos5260-based Samsung board.
- "samsung,smdk5410" - for Exynos5410-based Samsung SMDK5410 eval board.
- "samsung,smdk5420" - for Exynos5420-based Samsung SMDK5420 eval board.
+ - "samsung,tm2" - for Exynos5433-based Samsung TM2 board.
+ - "samsung,tm2e" - for Exynos5433-based Samsung TM2E board.
- "samsung,sd5v1" - for Exynos5440-based Samsung board.
- "samsung,ssdk5440" - for Exynos5440-based Samsung board.
@@ -22,6 +24,9 @@ Required root node properties:
* FriendlyARM
- "friendlyarm,tiny4412" - for Exynos4412-based FriendlyARM
TINY4412 board.
+ * TOPEET
+ - "topeet,itop4412-elite" - for Exynos4412-based TOPEET
+ Elite base board.
* Google
- "google,pi" - for Exynos5800-based Google Peach Pi
diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt
index 2f0b7169f132..253bf9b86690 100644
--- a/Documentation/devicetree/bindings/arm/shmobile.txt
+++ b/Documentation/devicetree/bindings/arm/shmobile.txt
@@ -13,6 +13,10 @@ SoCs:
compatible = "renesas,r8a73a4"
- R-Mobile A1 (R8A77400)
compatible = "renesas,r8a7740"
+ - RZ/G1M (R8A77430)
+ compatible = "renesas,r8a7743"
+ - RZ/G1E (R8A77450)
+ compatible = "renesas,r8a7745"
- R-Car M1A (R8A77781)
compatible = "renesas,r8a7778"
- R-Car H1 (R8A77790)
@@ -35,7 +39,7 @@ SoCs:
Boards:
- - Alt
+ - Alt (RTP0RC7794SEB00010S)
compatible = "renesas,alt", "renesas,r8a7794"
- APE6-EVM
compatible = "renesas,ape6evm", "renesas,r8a73a4"
@@ -47,9 +51,9 @@ Boards:
compatible = "renesas,bockw", "renesas,r8a7778"
- Genmai (RTK772100BC00000BR)
compatible = "renesas,genmai", "renesas,r7s72100"
- - Gose
+ - Gose (RTP0RC7793SEB00010S)
compatible = "renesas,gose", "renesas,r8a7793"
- - H3ULCB (RTP0RC7795SKB00010S)
+ - H3ULCB (R-Car Starter Kit Premier, RTP0RC7795SKB00010S)
compatible = "renesas,h3ulcb", "renesas,r8a7795";
- Henninger
compatible = "renesas,henninger", "renesas,r8a7791"
@@ -61,7 +65,9 @@ Boards:
compatible = "renesas,kzm9g", "renesas,sh73a0"
- Lager (RTP0RC7790SEB00010S)
compatible = "renesas,lager", "renesas,r8a7790"
- - Marzen
+ - M3ULCB (R-Car Starter Kit Pro, RTP0RC7796SKB00010S)
+ compatible = "renesas,m3ulcb", "renesas,r8a7796";
+ - Marzen (R0P7779A00010S)
compatible = "renesas,marzen", "renesas,r8a7779"
- Porter (M2-LCDP)
compatible = "renesas,porter", "renesas,r8a7791"
@@ -73,5 +79,27 @@ Boards:
compatible = "renesas,salvator-x", "renesas,r8a7796";
- SILK (RTP0RC7794LCB00011S)
compatible = "renesas,silk", "renesas,r8a7794"
+ - SK-RZG1E (YR8A77450S000BE)
+ compatible = "renesas,sk-rzg1e", "renesas,r8a7745"
+ - SK-RZG1M (YR8A77430S000BE)
+ compatible = "renesas,sk-rzg1m", "renesas,r8a7743"
- Wheat
compatible = "renesas,wheat", "renesas,r8a7792"
+
+
+Most Renesas ARM SoCs have a Product Register that allows to retrieve SoC
+product and revision information. If present, a device node for this register
+should be added.
+
+Required properties:
+ - compatible: Must be "renesas,prr".
+ - reg: Base address and length of the register block.
+
+
+Examples
+--------
+
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt
index 3975d0a0e4c2..4d6467cc2aa2 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.txt
+++ b/Documentation/devicetree/bindings/arm/sunxi.txt
@@ -14,4 +14,5 @@ using one of the following compatible strings:
allwinner,sun8i-a83t
allwinner,sun8i-h3
allwinner,sun9i-a80
+ allwinner,sun50i-a64
nextthing,gr8
diff --git a/Documentation/devicetree/bindings/arm/swir.txt b/Documentation/devicetree/bindings/arm/swir.txt
new file mode 100644
index 000000000000..042be73a95d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/swir.txt
@@ -0,0 +1,12 @@
+Sierra Wireless Modules device tree bindings
+--------------------------------------------
+
+Supported Modules :
+ - WP8548 : Includes MDM9615 and PM8018 in a module
+
+Sierra Wireless modules shall have the following properties :
+ Required root node property
+ - compatible: "swir,wp8548" for the WP8548 CF3 Module
+
+Board compatible values:
+ - "swir,mangoh-green-wp8548" for the mangOH green board with the WP8548 module
diff --git a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
index 032a7606b862..fc33ca01e9ba 100644
--- a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt
@@ -3,7 +3,7 @@ Binding for Freescale QorIQ AHCI SATA Controller
Required properties:
- reg: Physical base address and size of the controller's register area.
- compatible: Compatibility string. Must be 'fsl,<chip>-ahci', where
- chip could be ls1021a, ls2080a, ls1043a etc.
+ chip could be ls1021a, ls1043a, ls1046a, ls2080a etc.
- clocks: Input clock specifier. Refer to common clock bindings.
- interrupts: Interrupt specifier. Refer to interrupt binding.
diff --git a/Documentation/devicetree/bindings/ata/ahci-st.txt b/Documentation/devicetree/bindings/ata/ahci-st.txt
index e1d01df8e3c1..909c9935360d 100644
--- a/Documentation/devicetree/bindings/ata/ahci-st.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-st.txt
@@ -18,21 +18,6 @@ Optional properties:
Example:
- /* Example for stih416 */
- sata0: sata@fe380000 {
- compatible = "st,ahci";
- reg = <0xfe380000 0x1000>;
- interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>;
- interrupt-names = "hostc";
- phys = <&phy_port0 PHY_TYPE_SATA>;
- phy-names = "ahci_phy";
- resets = <&powerdown STIH416_SATA0_POWERDOWN>,
- <&softreset STIH416_SATA0_SOFTRESET>;
- reset-names = "pwr-dwn", "sw-rst";
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- clock-names = "ahci_clk";
- };
-
/* Example for stih407 family silicon */
sata0: sata@9b20000 {
compatible = "st,ahci";
diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
new file mode 100644
index 000000000000..83b0e54f727c
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
@@ -0,0 +1,132 @@
+Device tree bindings for NVIDIA Tegra Generic Memory Interface bus
+
+The Generic Memory Interface bus enables memory transfers between internal and
+external memory. Can be used to attach various high speed devices such as
+synchronous/asynchronous NOR, FPGA, UARTS and more.
+
+The actual devices are instantiated from the child nodes of a GMI node.
+
+Required properties:
+ - compatible : Should contain one of the following:
+ For Tegra20 must contain "nvidia,tegra20-gmi".
+ For Tegra30 must contain "nvidia,tegra30-gmi".
+ - reg: Should contain GMI controller registers location and length.
+ - clocks: Must contain an entry for each entry in clock-names.
+ - clock-names: Must include the following entries: "gmi"
+ - resets : Must contain an entry for each entry in reset-names.
+ - reset-names : Must include the following entries: "gmi"
+ - #address-cells: The number of cells used to represent physical base
+ addresses in the GMI address space. Should be 2.
+ - #size-cells: The number of cells used to represent the size of an address
+ range in the GMI address space. Should be 1.
+ - ranges: Must be set up to reflect the memory layout with three integer values
+ for each chip-select line in use (only one entry is supported, see below
+ comments):
+ <cs-number> <offset> <physical address of mapping> <size>
+
+Note that the GMI controller does not have any internal chip-select address
+decoding, because of that chip-selects either need to be managed via software
+or by employing external chip-select decoding logic.
+
+If external chip-select logic is used to support multiple devices it is assumed
+that the devices use the same timing and so are probably the same type. It also
+assumes that they can fit in the 256MB address range. In this case only one
+child device is supported which represents the active chip-select line, see
+examples for more insight.
+
+The chip-select number is decoded from the child nodes second address cell of
+'ranges' property, if 'ranges' property is not present or empty chip-select will
+then be decoded from the first cell of the 'reg' property.
+
+Optional child cs node properties:
+
+ - nvidia,snor-data-width-32bit: Use 32bit data-bus, default is 16bit.
+ - nvidia,snor-mux-mode: Enable address/data MUX mode.
+ - nvidia,snor-rdy-active-before-data: Assert RDY signal one cycle before data.
+ If omitted it will be asserted with data.
+ - nvidia,snor-rdy-active-high: RDY signal is active high
+ - nvidia,snor-adv-active-high: ADV signal is active high
+ - nvidia,snor-oe-active-high: WE/OE signal is active high
+ - nvidia,snor-cs-active-high: CS signal is active high
+
+ Note that there is some special handling for the timing values.
+ From Tegra TRM:
+ Programming 0 means 1 clock cycle: actual cycle = programmed cycle + 1
+
+ - nvidia,snor-muxed-width: Number of cycles MUX address/data asserted on the
+ bus. Valid values are 0-15, default is 1
+ - nvidia,snor-hold-width: Number of cycles CE stays asserted after the
+ de-assertion of WR_N (in case of SLAVE/MASTER Request) or OE_N
+ (in case of MASTER Request). Valid values are 0-15, default is 1
+ - nvidia,snor-adv-width: Number of cycles during which ADV stays asserted.
+ Valid values are 0-15, default is 1.
+ - nvidia,snor-ce-width: Number of cycles before CE is asserted.
+ Valid values are 0-15, default is 4
+ - nvidia,snor-we-width: Number of cycles during which WE stays asserted.
+ Valid values are 0-15, default is 1
+ - nvidia,snor-oe-width: Number of cycles during which OE stays asserted.
+ Valid values are 0-255, default is 1
+ - nvidia,snor-wait-width: Number of cycles before READY is asserted.
+ Valid values are 0-255, default is 3
+
+Example with two SJA1000 CAN controllers connected to the GMI bus. We wrap the
+controllers with a simple-bus node since they are all connected to the same
+chip-select (CS4), in this example external address decoding is provided:
+
+gmi@70090000 {
+ compatible = "nvidia,tegra20-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&tegra_car TEGRA20_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ ranges = <4 0 0xd0000000 0xfffffff>;
+
+ status = "okay";
+
+ bus@4,0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 4 0 0x40100>;
+
+ nvidia,snor-mux-mode;
+ nvidia,snor-adv-active-high;
+
+ can@0 {
+ reg = <0 0x100>;
+ ...
+ };
+
+ can@40000 {
+ reg = <0x40000 0x100>;
+ ...
+ };
+ };
+};
+
+Example with one SJA1000 CAN controller connected to the GMI bus
+on CS4:
+
+gmi@70090000 {
+ compatible = "nvidia,tegra20-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&tegra_car TEGRA20_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ ranges = <4 0 0xd0000000 0xfffffff>;
+
+ status = "okay";
+
+ can@4,0 {
+ reg = <4 0 0x100>;
+ nvidia,snor-mux-mode;
+ nvidia,snor-adv-active-high;
+ ...
+ };
+};
diff --git a/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
new file mode 100644
index 000000000000..72daefc6b4a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx master peripheral
+ priority driver
+
+DA8XX SoCs feature a set of registers allowing to change the priority of all
+peripherals classified as masters.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible: "ti,da850-mstpri" - for da850 based boards
+- reg: offset and length of the mstpri registers
+
+Example for da850-lcdk is shown below.
+
+mstpri {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+};
diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Documentation/devicetree/bindings/clock/imx31-clock.txt
index 19df842c694f..8163d565f697 100644
--- a/Documentation/devicetree/bindings/clock/imx31-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx31-clock.txt
@@ -77,7 +77,7 @@ Examples:
clks: ccm@53f80000{
compatible = "fsl,imx31-ccm";
reg = <0x53f80000 0x4000>;
- interrupts = <0 31 0x04 0 53 0x04>;
+ interrupts = <31>, <53>;
#clock-cells = <1>;
};
diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
index 16a3ec433119..df9cb5ac5f72 100644
--- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
+++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
@@ -32,6 +32,9 @@ Required properties:
* "fsl,b4420-clockgen"
* "fsl,b4860-clockgen"
* "fsl,ls1021a-clockgen"
+ * "fsl,ls1043a-clockgen"
+ * "fsl,ls1046a-clockgen"
+ * "fsl,ls2080a-clockgen"
Chassis-version clock strings include:
* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
* "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks
diff --git a/Documentation/devicetree/bindings/dma/nbpfaxi.txt b/Documentation/devicetree/bindings/dma/nbpfaxi.txt
index d5e2522b9ec1..d2e1e62e346a 100644
--- a/Documentation/devicetree/bindings/dma/nbpfaxi.txt
+++ b/Documentation/devicetree/bindings/dma/nbpfaxi.txt
@@ -23,6 +23,14 @@ Required properties
#define NBPF_SLAVE_RQ_LEVEL 4
Optional properties:
+- max-burst-mem-read: limit burst size for memory reads
+ (DMA_MEM_TO_MEM/DMA_MEM_TO_DEV) to this value, specified in bytes, rather
+ than using the maximum burst size allowed by the hardware's buffer size.
+- max-burst-mem-write: limit burst size for memory writes
+ (DMA_DEV_TO_MEM/DMA_MEM_TO_MEM) to this value, specified in bytes, rather
+ than using the maximum burst size allowed by the hardware's buffer size.
+ If both max-burst-mem-read and max-burst-mem-write are set, DMA_MEM_TO_MEM
+ will use the lower value.
You can use dma-channels and dma-requests as described in dma.txt, although they
won't be used, this information is derived from the compatibility string.
diff --git a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
index fd5618bd8fbc..55492c264d17 100644
--- a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
@@ -5,13 +5,13 @@ memcpy and memset capabilities. It has been designed for virtualized
environments.
Each HIDMA HW instance consists of multiple DMA channels. These channels
-share the same bandwidth. The bandwidth utilization can be parititioned
+share the same bandwidth. The bandwidth utilization can be partitioned
among channels based on the priority and weight assignments.
There are only two priority levels and 15 weigh assignments possible.
Other parameters here determine how much of the system bus this HIDMA
-instance can use like maximum read/write request and and number of bytes to
+instance can use like maximum read/write request and number of bytes to
read/write in a single burst.
Main node required properties:
@@ -47,12 +47,18 @@ When the OS is not in control of the management interface (i.e. it's a guest),
the channel nodes appear on their own, not under a management node.
Required properties:
-- compatible: must contain "qcom,hidma-1.0"
+- compatible: must contain "qcom,hidma-1.0" for initial HW or "qcom,hidma-1.1"
+for MSI capable HW.
- reg: Addresses for the transfer and event channel
- interrupts: Should contain the event interrupt
- desc-count: Number of asynchronous requests this channel can handle
- iommus: required a iommu node
+Optional properties for MSI:
+- msi-parent : See the generic MSI binding described in
+ devicetree/bindings/interrupt-controller/msi.txt for a description of the
+ msi-parent property.
+
Example:
Hypervisor OS configuration:
diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
index 5f2ce669789a..3316a9c2e638 100644
--- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
+++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
@@ -24,6 +24,7 @@ Required Properties:
- "renesas,dmac-r8a7793" (R-Car M2-N)
- "renesas,dmac-r8a7794" (R-Car E2)
- "renesas,dmac-r8a7795" (R-Car H3)
+ - "renesas,dmac-r8a7796" (R-Car M3-W)
- reg: base address and length of the registers block for the DMAC
diff --git a/Documentation/devicetree/bindings/dma/snps-dma.txt b/Documentation/devicetree/bindings/dma/snps-dma.txt
index 0f5583293c9c..4775c66f4508 100644
--- a/Documentation/devicetree/bindings/dma/snps-dma.txt
+++ b/Documentation/devicetree/bindings/dma/snps-dma.txt
@@ -27,6 +27,8 @@ Optional properties:
that services interrupts for this device
- is_private: The device channels should be marked as private and not for by the
general purpose DMA channel allocator. False if not passed.
+- multi-block: Multi block transfers supported by hardware. Array property with
+ one cell per channel. 0: not supported, 1 (default): supported.
Example:
diff --git a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
new file mode 100644
index 000000000000..e821e16ad65b
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
@@ -0,0 +1,108 @@
+NVIDIA Tegra Boot and Power Management Processor (BPMP)
+
+The BPMP is a specific processor in Tegra chip, which is designed for
+booting process handling and offloading the power management, clock
+management, and reset control tasks from the CPU. The binding document
+defines the resources that would be used by the BPMP firmware driver,
+which can create the interprocessor communication (IPC) between the CPU
+and BPMP.
+
+Required properties:
+- name : Should be bpmp
+- compatible
+ Array of strings
+ One of:
+ - "nvidia,tegra186-bpmp"
+- mboxes : The phandle of mailbox controller and the mailbox specifier.
+- shmem : List of the phandle of the TX and RX shared memory area that
+ the IPC between CPU and BPMP is based on.
+- #clock-cells : Should be 1.
+- #power-domain-cells : Should be 1.
+- #reset-cells : Should be 1.
+
+This node is a mailbox consumer. See the following files for details of
+the mailbox subsystem, and the specifiers implemented by the relevant
+provider(s):
+
+- .../mailbox/mailbox.txt
+- .../mailbox/nvidia,tegra186-hsp.txt
+
+This node is a clock, power domain, and reset provider. See the following
+files for general documentation of those features, and the specifiers
+implemented by this node:
+
+- .../clock/clock-bindings.txt
+- <dt-bindings/clock/tegra186-clock.h>
+- ../power/power_domain.txt
+- <dt-bindings/power/tegra186-powergate.h>
+- .../reset/reset.txt
+- <dt-bindings/reset/tegra186-reset.h>
+
+The BPMP implements some services which must be represented by separate nodes.
+For example, it can provide access to certain I2C controllers, and the I2C
+bindings represent each I2C controller as a device tree node. Such nodes should
+be nested directly inside the main BPMP node.
+
+Software can determine whether a child node of the BPMP node represents a device
+by checking for a compatible property. Any node with a compatible property
+represents a device that can be instantiated. Nodes without a compatible
+property may be used to provide configuration information regarding the BPMP
+itself, although no such configuration nodes are currently defined by this
+binding.
+
+The BPMP firmware defines no single global name-/numbering-space for such
+services. Put another way, the numbering scheme for I2C buses is distinct from
+the numbering scheme for any other service the BPMP may provide (e.g. a future
+hypothetical SPI bus service). As such, child device nodes will have no reg
+property, and the BPMP node will have no #address-cells or #size-cells property.
+
+The shared memory bindings for BPMP
+-----------------------------------
+
+The shared memory area for the IPC TX and RX between CPU and BPMP are
+predefined and work on top of sysram, which is an SRAM inside the chip.
+
+See ".../sram/sram.txt" for the bindings.
+
+Example:
+
+hsp_top0: hsp@03c00000 {
+ ...
+ #mbox-cells = <2>;
+};
+
+sysram@30000000 {
+ compatible = "nvidia,tegra186-sysram", "mmio-sram";
+ reg = <0x0 0x30000000 0x0 0x50000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0 0x0 0x0 0x30000000 0x0 0x50000>;
+
+ cpu_bpmp_tx: shmem@4e000 {
+ compatible = "nvidia,tegra186-bpmp-shmem";
+ reg = <0x0 0x4e000 0x0 0x1000>;
+ label = "cpu-bpmp-tx";
+ pool;
+ };
+
+ cpu_bpmp_rx: shmem@4f000 {
+ compatible = "nvidia,tegra186-bpmp-shmem";
+ reg = <0x0 0x4f000 0x0 0x1000>;
+ label = "cpu-bpmp-rx";
+ pool;
+ };
+};
+
+bpmp {
+ compatible = "nvidia,tegra186-bpmp";
+ mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB TEGRA_HSP_DB_MASTER_BPMP>;
+ shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ #reset-cells = <1>;
+
+ i2c {
+ compatible = "...";
+ ...
+ };
+};
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
index 3b4436e56865..20f26fbce875 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
@@ -10,8 +10,10 @@ Required properties:
* "qcom,scm-apq8064" for APQ8064 platforms
* "qcom,scm-msm8660" for MSM8660 platforms
* "qcom,scm-msm8690" for MSM8690 platforms
+ * "qcom,scm-msm8996" for MSM8996 platforms
* "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc)
- clocks: One to three clocks may be required based on compatible.
+ * No clock required for "qcom,scm-msm8996"
* Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960"
* Core, iface, and bus clocks required for "qcom,scm"
- clock-names: Must contain "core" for the core clock, "iface" for the interface
diff --git a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
new file mode 100644
index 000000000000..817a8d4bf903
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
@@ -0,0 +1,16 @@
+Altera FPGA To SDRAM Bridge Driver
+
+Required properties:
+- compatible : Should contain "altr,socfpga-fpga2sdram-bridge"
+
+Optional properties:
+- bridge-enable : 0 if driver should disable bridge at startup
+ 1 if driver should enable bridge at startup
+ Default is to leave bridge in current state.
+
+Example:
+ fpga_bridge3: fpga-bridge@ffc25080 {
+ compatible = "altr,socfpga-fpga2sdram-bridge";
+ reg = <0xffc25080 0x4>;
+ bridge-enable = <0>;
+ };
diff --git a/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
new file mode 100644
index 000000000000..f8e288c71b2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
@@ -0,0 +1,23 @@
+Altera Freeze Bridge Controller Driver
+
+The Altera Freeze Bridge Controller manages one or more freeze bridges.
+The controller can freeze/disable the bridges which prevents signal
+changes from passing through the bridge. The controller can also
+unfreeze/enable the bridges which allows traffic to pass through the
+bridge normally.
+
+Required properties:
+- compatible : Should contain "altr,freeze-bridge-controller"
+- regs : base address and size for freeze bridge module
+
+Optional properties:
+- bridge-enable : 0 if driver should disable bridge at startup
+ 1 if driver should enable bridge at startup
+ Default is to leave bridge in current state.
+
+Example:
+ freeze-controller@100000450 {
+ compatible = "altr,freeze-bridge-controller";
+ regs = <0x1000 0x10>;
+ bridge-enable = <0>;
+ };
diff --git a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
new file mode 100644
index 000000000000..6406f9337eeb
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
@@ -0,0 +1,39 @@
+Altera FPGA/HPS Bridge Driver
+
+Required properties:
+- regs : base address and size for AXI bridge module
+- compatible : Should contain one of:
+ "altr,socfpga-lwhps2fpga-bridge",
+ "altr,socfpga-hps2fpga-bridge", or
+ "altr,socfpga-fpga2hps-bridge"
+- resets : Phandle and reset specifier for this bridge's reset
+- clocks : Clocks used by this module.
+
+Optional properties:
+- bridge-enable : 0 if driver should disable bridge at startup.
+ 1 if driver should enable bridge at startup.
+ Default is to leave bridge in its current state.
+
+Example:
+ fpga_bridge0: fpga-bridge@ff400000 {
+ compatible = "altr,socfpga-lwhps2fpga-bridge";
+ reg = <0xff400000 0x100000>;
+ resets = <&rst LWHPS2FPGA_RESET>;
+ clocks = <&l4_main_clk>;
+ bridge-enable = <0>;
+ };
+
+ fpga_bridge1: fpga-bridge@ff500000 {
+ compatible = "altr,socfpga-hps2fpga-bridge";
+ reg = <0xff500000 0x10000>;
+ resets = <&rst HPS2FPGA_RESET>;
+ clocks = <&l4_main_clk>;
+ bridge-enable = <1>;
+ };
+
+ fpga_bridge2: fpga-bridge@ff600000 {
+ compatible = "altr,socfpga-fpga2hps-bridge";
+ reg = <0xff600000 0x100000>;
+ resets = <&rst FPGA2HPS_RESET>;
+ clocks = <&l4_main_clk>;
+ };
diff --git a/Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt
new file mode 100644
index 000000000000..2fd8e7a84734
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt
@@ -0,0 +1,19 @@
+Altera SOCFPGA Arria10 FPGA Manager
+
+Required properties:
+- compatible : should contain "altr,socfpga-a10-fpga-mgr"
+- reg : base address and size for memory mapped io.
+ - The first index is for FPGA manager register access.
+ - The second index is for writing FPGA configuration data.
+- resets : Phandle and reset specifier for the device's reset.
+- clocks : Clocks used by the device.
+
+Example:
+
+ fpga_mgr: fpga-mgr@ffd03000 {
+ compatible = "altr,socfpga-a10-fpga-mgr";
+ reg = <0xffd03000 0x100
+ 0xffcfe400 0x20>;
+ clocks = <&l4_mp_clk>;
+ resets = <&rst FPGAMGR_RESET>;
+ };
diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
index c3d016532d8e..30fd2201b3d4 100644
--- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
@@ -17,7 +17,9 @@ Required properties:
- #interrupt-cells: Specifies the number of cells needed to encode an
interrupt source.
- gpio-controller : Marks the device node as a gpio controller.
-- #gpio-cells : Should be one. It is the pin number.
+- #gpio-cells : Should be two. The first cell is the pin number and
+ the second cell is used to specify flags. See gpio.txt for possible
+ values.
Example for a MMP platform:
@@ -27,7 +29,7 @@ Example for a MMP platform:
interrupts = <49>;
interrupt-names = "gpio_mux";
gpio-controller;
- #gpio-cells = <1>;
+ #gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt b/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
new file mode 100644
index 000000000000..70c054a9a997
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
@@ -0,0 +1,20 @@
+* Freescale Low Power Inter IC (LPI2C) for i.MX
+
+Required properties:
+- compatible :
+ - "fsl,imx7ulp-lpi2c" for LPI2C compatible with the one integrated on i.MX7ULP soc
+ - "fsl,imx8dv-lpi2c" for LPI2C compatible with the one integrated on i.MX8DV soc
+- reg : address and length of the lpi2c master registers
+- interrupt-parent : core interrupt controller
+- interrupts : lpi2c interrupt
+- clocks : lpi2c clock specifier
+
+Examples:
+
+lpi2c7: lpi2c7@40A50000 {
+ compatible = "fsl,imx8dv-lpi2c";
+ reg = <0x40A50000 0x10000>;
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7ULP_CLK_LPI2C7>;
+};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 12b78ac507e9..d30f0b11d853 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -7,6 +7,7 @@ Required properties :
compatible processor, e.g. pxa168, pxa910, mmp2, mmp3.
For the pxa2xx/pxa3xx, an additional node "mrvl,pxa-i2c" is required
as shown in the example below.
+ For the Armada 3700, the compatible should be "marvell,armada-3700-i2c".
Recommended properties :
diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt
index 239632a0d709..2b8bd33dbf8d 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt
@@ -1,17 +1,25 @@
I2C for R-Car platforms
Required properties:
-- compatible: Must be one of
- "renesas,i2c-rcar"
- "renesas,i2c-r8a7778"
- "renesas,i2c-r8a7779"
- "renesas,i2c-r8a7790"
- "renesas,i2c-r8a7791"
- "renesas,i2c-r8a7792"
- "renesas,i2c-r8a7793"
- "renesas,i2c-r8a7794"
- "renesas,i2c-r8a7795"
- "renesas,i2c-r8a7796"
+- compatible:
+ "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
+ "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
+ "renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC.
+ "renesas,i2c-r8a7791" if the device is a part of a R8A7791 SoC.
+ "renesas,i2c-r8a7792" if the device is a part of a R8A7792 SoC.
+ "renesas,i2c-r8a7793" if the device is a part of a R8A7793 SoC.
+ "renesas,i2c-r8a7794" if the device is a part of a R8A7794 SoC.
+ "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC.
+ "renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC.
+ "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device.
+ "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 compatible device.
+ "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 compatible device.
+ "renesas,i2c-rcar" (deprecated)
+
+ When compatible with the generic version, nodes must list the
+ SoC-specific version corresponding to the platform first followed
+ by the generic version.
+
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt specifier.
@@ -33,7 +41,7 @@ Examples :
i2c0: i2c@e6508000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "renesas,i2c-r8a7791";
+ compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
reg = <0 0xe6508000 0 0x40>;
interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
diff --git a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
index 214f94c25d37..7716acc55dec 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
@@ -1,8 +1,7 @@
Device tree configuration for Renesas IIC (sh_mobile) driver
Required properties:
-- compatible : "renesas,iic-<soctype>". "renesas,rmobile-iic" as fallback
- Examples with soctypes are:
+- compatible :
- "renesas,iic-r8a73a4" (R-Mobile APE6)
- "renesas,iic-r8a7740" (R-Mobile A1)
- "renesas,iic-r8a7790" (R-Car H2)
@@ -12,6 +11,17 @@ Required properties:
- "renesas,iic-r8a7794" (R-Car E2)
- "renesas,iic-r8a7795" (R-Car H3)
- "renesas,iic-sh73a0" (SH-Mobile AG5)
+ - "renesas,rcar-gen2-iic" (generic R-Car Gen2 compatible device)
+ - "renesas,rcar-gen3-iic" (generic R-Car Gen3 compatible device)
+ - "renesas,rmobile-iic" (generic device)
+
+ When compatible with a generic R-Car version, nodes
+ must list the SoC-specific version corresponding to
+ the platform first followed by the generic R-Car
+ version.
+
+ renesas,rmobile-iic must always follow.
+
- reg : address start and address range size of device
- interrupts : interrupt of device
- clocks : clock for device
@@ -31,7 +41,8 @@ Pinctrl properties might be needed, too. See there.
Example:
iic0: i2c@e6500000 {
- compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic";
+ compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
+ "renesas,rmobile-iic";
reg = <0 0xe6500000 0 0x425>;
interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index df720ca00fcf..ff86fdcbd353 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -138,6 +138,8 @@ nuvoton,npct501 i2c trusted platform module (TPM)
nuvoton,npct601 i2c trusted platform module (TPM2)
nxp,pca9556 Octal SMBus and I2C registered interface
nxp,pca9557 8-bit I2C-bus and SMBus I/O port with reset
+nxp,pcf2127 Real-time clock
+nxp,pcf2129 Real-time clock
nxp,pcf8563 Real-time clock/calendar
nxp,pcf85063 Tiny Real-Time Clock
oki,ml86v7667 OKI ML86V7667 video decoder
diff --git a/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt b/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt
index e893615ef635..b48d7d30012c 100644
--- a/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt
+++ b/Documentation/devicetree/bindings/mailbox/brcm,bcm2835-mbox.txt
@@ -12,7 +12,7 @@ Required properties:
Example:
-mailbox: mailbox@7e00b800 {
+mailbox: mailbox@7e00b880 {
compatible = "brcm,bcm2835-mbox";
reg = <0x7e00b880 0x40>;
interrupts = <0 1>;
diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
new file mode 100644
index 000000000000..b99d25fc2f26
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
@@ -0,0 +1,52 @@
+NVIDIA Tegra Hardware Synchronization Primitives (HSP)
+
+The HSP modules are used for the processors to share resources and communicate
+together. It provides a set of hardware synchronization primitives for
+interprocessor communication. So the interprocessor communication (IPC)
+protocols can use hardware synchronization primitives, when operating between
+two processors not in an SMP relationship.
+
+The features that HSP supported are shared mailboxes, shared semaphores,
+arbitrated semaphores and doorbells.
+
+Required properties:
+- name : Should be hsp
+- compatible
+ Array of strings.
+ one of:
+ - "nvidia,tegra186-hsp"
+- reg : Offset and length of the register set for the device.
+- interrupt-names
+ Array of strings.
+ Contains a list of names for the interrupts described by the interrupt
+ property. May contain the following entries, in any order:
+ - "doorbell"
+ Users of this binding MUST look up entries in the interrupt property
+ by name, using this interrupt-names property to do so.
+- interrupts
+ Array of interrupt specifiers.
+ Must contain one entry per entry in the interrupt-names property,
+ in a matching order.
+- #mbox-cells : Should be 2.
+
+The mbox specifier of the "mboxes" property in the client node should
+contain two data. The first one should be the HSP type and the second
+one should be the ID that the client is going to use. Those information
+can be found in the following file.
+
+- <dt-bindings/mailbox/tegra186-hsp.h>.
+
+Example:
+
+hsp_top0: hsp@3c00000 {
+ compatible = "nvidia,tegra186-hsp";
+ reg = <0x0 0x03c00000 0x0 0xa0000>;
+ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "doorbell";
+ #mbox-cells = <2>;
+};
+
+client {
+ ...
+ mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB TEGRA_HSP_DB_MASTER_XXX>;
+};
diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt
index 27f9b8e459ac..3ec91803ba58 100644
--- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
+++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
@@ -11,15 +11,9 @@ are paired with. These DT bindings currently support the FCPV and FCPF.
- compatible: Must be one or more of the following
- - "renesas,r8a7795-fcpv" for R8A7795 (R-Car H3) compatible 'FCP for VSP'
- - "renesas,r8a7795-fcpf" for R8A7795 (R-Car H3) compatible 'FCP for FDP'
- "renesas,fcpv" for generic compatible 'FCP for VSP'
- "renesas,fcpf" for generic compatible 'FCP for FDP'
- When compatible with the generic version, nodes must list the
- SoC-specific version corresponding to the platform first, followed by the
- family-specific and/or generic versions.
-
- reg: the register base and size for the device registers
- clocks: Reference to the functional clock
@@ -32,7 +26,7 @@ Device node example
-------------------
fcpvd1: fcp@fea2f000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfea2f000 0 0x200>;
clocks = <&cpg CPG_MOD 602>;
power-domains = <&sysc R8A7795_PD_A3VP>;
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
new file mode 100644
index 000000000000..ec1dd408d573
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx DDR2/mDDR memory controller
+
+The DDR2/mDDR memory controller present on Texas Instruments da8xx SoCs features
+a set of registers which allow to tweak the controller's behavior.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible: "ti,da850-ddr-controller" - for da850 SoC based boards
+- reg: a tuple containing the base address of the memory
+ controller and the size of the memory area to map
+
+Example for da850 shown below.
+
+ddrctl {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+};
diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index 07184e8f894e..ea9c1c9607f6 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -13,6 +13,7 @@ Required Properties:
- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
before RK3288
- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
+ - "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK1108
- "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036
- "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368
- "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399
diff --git a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
index 01b88f4e0d5b..b8e48b4762b2 100644
--- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
@@ -1,10 +1,17 @@
* Broadcom iProc PCIe controller with the platform bus interface
Required properties:
-- 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
+- compatible:
+ "brcm,iproc-pcie" for the first generation of PAXB based controller,
+used in SoCs including NSP, Cygnus, NS2, and Pegasus
+ "brcm,iproc-pcie-paxb-v2" for the second generation of PAXB-based
+controllers, used in Stingray
+ "brcm,iproc-pcie-paxc" for the first generation of PAXC based
+controller, used in NS2
+ "brcm,iproc-pcie-paxc-v2" for the second generation of PAXC based
+controller, used in Stingray
+ 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
@@ -19,6 +26,10 @@ Required properties:
Optional properties:
- phys: phandle of the PCIe PHY device
- phy-names: must be "pcie-phy"
+- dma-coherent: present if DMA operations are coherent
+- dma-ranges: Some PAXB-based root complexes do not have inbound mapping done
+ by the ASIC after power on reset. In this case, SW is required to configure
+the mapping, based on inbound memory regions specified by this property.
- brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done
by the ASIC after power on reset. In this case, SW needs to configure it
@@ -29,11 +40,6 @@ effective:
Required:
- brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal
address used by the iProc PCIe core (not the PCIe address)
-- brcm,pcie-ob-window-size: The outbound address mapping window size (in MB)
-
-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):
@@ -41,10 +47,19 @@ 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.
+On newer iProc platforms, gicv2m or gicv3-its based MSI support should be used
+
+- msi-map: Maps a Requester ID to an MSI controller and associated MSI
+sideband data
+
+- msi-parent: Link to the device node of the MSI controller, used when no MSI
+sideband data is passed between the iProc PCIe controller and the MSI
+controller
+
+Refer to the following binding documents for more detailed description on
+the use of 'msi-map' and 'msi-parent':
+ Documentation/devicetree/bindings/pci/pci-msi.txt
+ Documentation/devicetree/bindings/interrupt-controller/msi.txt
When the iProc event queue based MSI is used, one needs to define the
following properties in the MSI device node:
@@ -80,9 +95,7 @@ Example:
phy-names = "pcie-phy";
brcm,pcie-ob;
- brcm,pcie-ob-oarr-size;
brcm,pcie-ob-axi-offset = <0x00000000>;
- brcm,pcie-ob-window-size = <256>;
msi-parent = <&msi0>;
diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt
index 41e9f55a1467..ee1c72d5162e 100644
--- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt
+++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt
@@ -15,6 +15,7 @@ Required properties:
- compatible: should contain the platform identifier such as:
"fsl,ls1021a-pcie", "snps,dw-pcie"
"fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie"
+ "fsl,ls1046a-pcie"
- reg: base addresses and lengths of the PCIe controller
- interrupts: A list of interrupt outputs of the controller. Must contain an
entry for each entry in the interrupt-names property.
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index b8cc395fffea..982a74ea6df9 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -110,6 +110,20 @@ Power supplies for Tegra124:
- avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must
supply 1.05 V.
+Power supplies for Tegra210:
+- Required:
+ - avdd-pll-uerefe-supply: Power supply for PLLE (shared with USB3). Must
+ supply 1.05 V.
+ - hvddio-pex-supply: High-voltage supply for PCIe I/O and PCIe output
+ clocks. Must supply 1.8 V.
+ - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
+ - dvdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
+ supply 1.05 V.
+ - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3).
+ Must supply 3.3 V.
+ - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
+ supply 1.8 V.
+
Root ports are defined as subnodes of the PCIe controller node.
Required properties:
@@ -436,3 +450,99 @@ Board DTS:
status = "okay";
};
};
+
+Tegra210:
+---------
+
+SoC DTSI:
+
+ pcie-controller@01003000 {
+ compatible = "nvidia,tegra210-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 TEGRA210_CLK_PCIE>,
+ <&tegra_car TEGRA210_CLK_AFI>,
+ <&tegra_car TEGRA210_CLK_PLL_E>,
+ <&tegra_car TEGRA210_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";
+
+ 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 = <4>;
+ };
+
+ 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>;
+ };
+ };
+
+Board DTS:
+
+ pcie-controller@01003000 {
+ status = "okay";
+
+ avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
+ hvddio-pex-supply = <&vdd_1v8>;
+ dvddio-pex-supply = <&vdd_pex_1v05>;
+ dvdd-pex-pll-supply = <&vdd_pex_1v05>;
+ hvdd-pex-pll-e-supply = <&vdd_1v8>;
+ vddio-pex-ctl-supply = <&vdd_1v8>;
+
+ pci@1,0 {
+ phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>;
+ phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
+ status = "okay";
+ };
+
+ pci@2,0 {
+ phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
+ phy-names = "pcie-0";
+ status = "okay";
+ };
+ };
diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt
index 08dcfad09f8d..50f9e2ca5b13 100644
--- a/Documentation/devicetree/bindings/pci/pci.txt
+++ b/Documentation/devicetree/bindings/pci/pci.txt
@@ -18,3 +18,9 @@ driver implementation may support the following properties:
host bridges in the system, otherwise potentially conflicting domain numbers
may be assigned to root buses behind different host bridges. The domain
number for each host bridge in the system must be unique.
+- max-link-speed:
+ If present this property specifies PCI gen for link capability. Host
+ drivers could add this as a strategy to avoid unnecessary operation for
+ unsupported link speed, for instance, trying to do training for
+ unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2'
+ for gen2, and '1' for gen1. Any other values are invalid.
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
index 4059a6f89bc1..e15f9b19901f 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
@@ -7,6 +7,7 @@
- "qcom,pcie-ipq8064" for ipq8064
- "qcom,pcie-apq8064" for apq8064
- "qcom,pcie-apq8084" for apq8084
+ - "qcom,pcie-msm8996" for msm8996 or apq8096
- reg:
Usage: required
@@ -92,6 +93,17 @@
- "aux" Auxiliary (AUX) clock
- "bus_master" Master AXI clock
- "bus_slave" Slave AXI clock
+
+- clock-names:
+ Usage: required for msm8996/apq8096
+ Value type: <stringlist>
+ Definition: Should contain the following entries
+ - "pipe" Pipe Clock driving internal logic
+ - "aux" Auxiliary (AUX) clock
+ - "cfg" Configuration clock
+ - "bus_master" Master AXI clock
+ - "bus_slave" Slave AXI clock
+
- resets:
Usage: required
Value type: <prop-encoded-array>
@@ -115,7 +127,7 @@
- "core" Core reset
- power-domains:
- Usage: required for apq8084
+ Usage: required for apq8084 and msm8996/apq8096
Value type: <prop-encoded-array>
Definition: A phandle and power domain specifier pair to the
power domain which is responsible for collapsing
diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt
index 6cf99690eef9..eee518db90b9 100644
--- a/Documentation/devicetree/bindings/pci/rcar-pci.txt
+++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt
@@ -7,6 +7,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC;
"renesas,pcie-r8a7793" for the R8A7793 SoC;
"renesas,pcie-r8a7795" for the R8A7795 SoC;
"renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device.
+ "renesas,pcie-rcar-gen3" for a generic R-Car Gen3 compatible device.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
index 66dcaa9efd74..e705acd3612c 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
@@ -7,6 +7,9 @@ Required properties:
- reg : offset and length of the register set for the mux registers
+- #pinctrl-cells : number of cells in addition to the index, set to 1
+ for pinctrl-single,pins and 2 for pinctrl-single,bits
+
- pinctrl-single,register-width : pinmux register access width in bits
- pinctrl-single,function-mask : mask of allowed pinmux function bits
diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
index 0725fb37a973..d91715bc8d52 100644
--- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
+++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
@@ -1,12 +1,14 @@
-DT bindings for the Renesas R-Car System Controller
+DT bindings for the Renesas R-Car (RZ/G) System Controller
== System Controller Node ==
-The R-Car System Controller provides power management for the CPU cores and
-various coprocessors.
+The R-Car (RZ/G) System Controller provides power management for the CPU cores
+and various coprocessors.
Required properties:
- compatible: Must contain exactly one of the following:
+ - "renesas,r8a7743-sysc" (RZ/G1M)
+ - "renesas,r8a7745-sysc" (RZ/G1E)
- "renesas,r8a7779-sysc" (R-Car H1)
- "renesas,r8a7790-sysc" (R-Car H2)
- "renesas,r8a7791-sysc" (R-Car M2-W)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt
index fb6fb31bc4c4..cf573e85b11d 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt
@@ -3,7 +3,7 @@ BCM2835 PWM controller (Raspberry Pi controller)
Required properties:
- compatible: should be "brcm,bcm2835-pwm"
- reg: physical base address and length of the controller's registers
-- clock: This clock defines the base clock frequency of the PWM hardware
+- clocks: This clock defines the base clock frequency of the PWM hardware
system, the period and the duty_cycle of the PWM signal is a multiple of
the base period.
- #pwm-cells: Should be 2. See pwm.txt in this directory for a description of
diff --git a/Documentation/devicetree/bindings/pwm/pwm-hibvt.txt b/Documentation/devicetree/bindings/pwm/pwm-hibvt.txt
new file mode 100644
index 000000000000..fa7849d67836
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-hibvt.txt
@@ -0,0 +1,21 @@
+Hisilicon PWM controller
+
+Required properties:
+-compatible: should contain one SoC specific compatible string
+ The SoC specific strings supported including:
+ "hisilicon,hi3516cv300-pwm"
+ "hisilicon,hi3519v100-pwm"
+- reg: physical base address and length of the controller's registers.
+- clocks: phandle and clock specifier of the PWM reference clock.
+- resets: phandle and reset specifier for the PWM controller reset.
+- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
+ the cells format.
+
+Example:
+ pwm: pwm@12130000 {
+ compatible = "hisilicon,hi3516cv300-pwm";
+ reg = <0x12130000 0x10000>;
+ clocks = <&crg_ctrl HI3516CV300_PWM_CLK>;
+ resets = <&crg_ctrl 0x38 0>;
+ #pwm-cells = <3>;
+ };
diff --git a/Documentation/devicetree/bindings/reset/oxnas,reset.txt b/Documentation/devicetree/bindings/reset/oxnas,reset.txt
index 6f06db930030..d27ccb5d04fc 100644
--- a/Documentation/devicetree/bindings/reset/oxnas,reset.txt
+++ b/Documentation/devicetree/bindings/reset/oxnas,reset.txt
@@ -5,45 +5,19 @@ Please also refer to reset.txt in this directory for common reset
controller binding usage.
Required properties:
-- compatible: Should be "oxsemi,ox810se-reset"
+- compatible: For OX810SE, should be "oxsemi,ox810se-reset"
+ For OX820, should be "oxsemi,ox820-reset"
- #reset-cells: 1, see below
Parent node should have the following properties :
-- compatible: Should be "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"
+- compatible: For OX810SE, should be :
+ "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"
+ For OX820, should be :
+ "oxsemi,ox820-sys-ctrl", "syscon", "simple-mfd"
-For OX810SE, the indices are :
- - 0 : ARM
- - 1 : COPRO
- - 2 : Reserved
- - 3 : Reserved
- - 4 : USBHS
- - 5 : USBHSPHY
- - 6 : MAC
- - 7 : PCI
- - 8 : DMA
- - 9 : DPE
- - 10 : DDR
- - 11 : SATA
- - 12 : SATA_LINK
- - 13 : SATA_PHY
- - 14 : Reserved
- - 15 : NAND
- - 16 : GPIO
- - 17 : UART1
- - 18 : UART2
- - 19 : MISC
- - 20 : I2S
- - 21 : AHB_MON
- - 22 : UART3
- - 23 : UART4
- - 24 : SGDMA
- - 25 : Reserved
- - 26 : Reserved
- - 27 : Reserved
- - 28 : Reserved
- - 29 : Reserved
- - 30 : Reserved
- - 31 : BUS
+Reset indices are in dt-bindings include files :
+- For OX810SE: include/dt-bindings/reset/oxsemi,ox810se.h
+- For OX820: include/dt-bindings/reset/oxsemi,ox820.h
example:
diff --git a/Documentation/devicetree/bindings/reset/st,sti-powerdown.txt b/Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
index 1cfd21d1dfa1..92527138bc93 100644
--- a/Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
+++ b/Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
@@ -16,15 +16,14 @@ Please refer to reset.txt in this directory for common reset
controller binding usage.
Required properties:
-- compatible: Should be "st,<chip>-powerdown"
- ex: "st,stih415-powerdown", "st,stih416-powerdown"
+- compatible: Should be "st,stih407-powerdown"
- #reset-cells: 1, see below
example:
powerdown: powerdown-controller {
+ compatible = "st,stih407-powerdown";
#reset-cells = <1>;
- compatible = "st,stih415-powerdown";
};
@@ -37,11 +36,10 @@ index specifying which channel to use, as described in reset.txt
example:
- usb1: usb@fe200000 {
- resets = <&powerdown STIH41X_USB1_POWERDOWN>;
+ st_dwc3: dwc3@8f94000 {
+ resets = <&powerdown STIH407_USB3_POWERDOWN>,
};
Macro definitions for the supported reset channels can be found in:
-include/dt-bindings/reset/stih415-resets.h
-include/dt-bindings/reset/stih416-resets.h
+include/dt-bindings/reset/stih407-resets.h
diff --git a/Documentation/devicetree/bindings/reset/st,sti-softreset.txt b/Documentation/devicetree/bindings/reset/st,sti-softreset.txt
index 891a2fd85ed6..a21658f18fe6 100644
--- a/Documentation/devicetree/bindings/reset/st,sti-softreset.txt
+++ b/Documentation/devicetree/bindings/reset/st,sti-softreset.txt
@@ -15,15 +15,14 @@ Please refer to reset.txt in this directory for common reset
controller binding usage.
Required properties:
-- compatible: Should be "st,<chip>-softreset" example:
- "st,stih415-softreset" or "st,stih416-softreset";
+- compatible: Should be st,stih407-softreset";
- #reset-cells: 1, see below
example:
softreset: softreset-controller {
#reset-cells = <1>;
- compatible = "st,stih415-softreset";
+ compatible = "st,stih407-softreset";
};
@@ -42,5 +41,4 @@ example:
Macro definitions for the supported reset channels can be found in:
-include/dt-bindings/reset/stih415-resets.h
-include/dt-bindings/reset/stih416-resets.h
+include/dt-bindings/reset/stih407-resets.h
diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt
index 845850caf088..c93a2d1c1a65 100644
--- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt
+++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt
@@ -10,7 +10,7 @@ Required properties:
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- serial
-- dmas : Must contain an entry for each entry in clock-names.
+- dmas : Must contain an entry for each entry in dma-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index e8f15e34027f..16fe94d7783c 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -9,17 +9,20 @@ domain control.
The driver implements the Generic PM domain bindings described in
power/power_domain.txt. It provides the power domains defined in
-include/dt-bindings/power/mt8173-power.h.
+include/dt-bindings/power/mt8173-power.h and mt2701-power.h.
Required properties:
-- compatible: Must be "mediatek,mt8173-scpsys"
+- compatible: Should be one of:
+ - "mediatek,mt2701-scpsys"
+ - "mediatek,mt8173-scpsys"
- #power-domain-cells: Must be 1
- reg: Address range of the SCPSYS unit
- infracfg: must contain a phandle to the infracfg controller
- clock, clock-names: clocks according to the common clock binding.
- The clocks needed "mm", "mfg", "venc" and "venc_lt".
- These are the clocks which hardware needs to be enabled
- before enabling certain power domains.
+ These are clocks which hardware needs to be
+ enabled before enabling certain power domains.
+ Required clocks for MT2701: "mm", "mfg", "ethif"
+ Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
Optional properties:
- vdec-supply: Power supply for the vdec power domain
diff --git a/Documentation/devicetree/bindings/sram/sram.txt b/Documentation/devicetree/bindings/sram/sram.txt
index add48f09015e..068c2c03c38f 100644
--- a/Documentation/devicetree/bindings/sram/sram.txt
+++ b/Documentation/devicetree/bindings/sram/sram.txt
@@ -4,7 +4,7 @@ Simple IO memory regions to be managed by the genalloc API.
Required properties:
-- compatible : mmio-sram
+- compatible : mmio-sram or atmel,sama5d2-securam
- reg : SRAM iomem address range
diff --git a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
new file mode 100644
index 000000000000..474531d2b2c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
@@ -0,0 +1,17 @@
+Binding for Thermal Sensor driver for BCM2835 SoCs.
+
+Required parameters:
+-------------------
+
+compatible: should be one of: "brcm,bcm2835-thermal",
+ "brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
+reg: Address range of the thermal registers.
+clocks: Phandle of the clock used by the thermal sensor.
+
+Example:
+
+thermal: thermal@7e212000 {
+ compatible = "brcm,bcm2835-thermal";
+ reg = <0x7e212000 0x8>;
+ clocks = <&clocks BCM2835_CLOCK_TSENS>;
+};
diff --git a/Documentation/devicetree/bindings/thermal/st-thermal.txt b/Documentation/devicetree/bindings/thermal/st-thermal.txt
index 3b9251b4a145..a2f939137e35 100644
--- a/Documentation/devicetree/bindings/thermal/st-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/st-thermal.txt
@@ -3,17 +3,8 @@ Binding for Thermal Sensor driver for STMicroelectronics STi series of SoCs.
Required parameters:
-------------------
-compatible : st,<SoC>-<module>-thermal; should be one of:
- "st,stih415-sas-thermal",
- "st,stih415-mpe-thermal",
- "st,stih416-sas-thermal"
- "st,stih416-mpe-thermal"
- "st,stid127-thermal" or
- "st,stih407-thermal"
- according to the SoC type (stih415, stih416, stid127, stih407)
- and module type (sas or mpe). On stid127 & stih407 there is only
- one die/module, so there is no module type in the compatible
- string.
+compatible : Should be "st,stih407-thermal"
+
clock-names : Should be "thermal".
See: Documentation/devicetree/bindings/resource-names.txt
clocks : Phandle of the clock used by the thermal sensor.
@@ -25,18 +16,17 @@ Optional parameters:
reg : For non-sysconf based sensors, this should be the physical base
address and length of the sensor's registers.
interrupts : Standard way to define interrupt number.
- Interrupt is mandatory to be defined when compatible is
- "stih416-mpe-thermal".
NB: For thermal sensor's for which no interrupt has been
defined, a polling delay of 1000ms will be used to read the
temperature from device.
Example:
- temp1@fdfe8000 {
- compatible = "st,stih416-mpe-thermal";
- reg = <0xfdfe8000 0x10>;
- clock-names = "thermal";
- clocks = <&clk_m_mpethsens>;
- interrupts = <GIC_SPI 23 IRQ_TYPE_NONE>;
+ temp0@91a0000 {
+ compatible = "st,stih407-thermal";
+ reg = <0x91a0000 0x28>;
+ clock-names = "thermal";
+ clocks = <&CLK_SYSIN>;
+ interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
+ st,passive_cooling_temp = <110>;
};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
new file mode 100644
index 000000000000..e3cfce8fecc5
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
@@ -0,0 +1,17 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-timer0"
+
+Clocks required for compatible = "ezchip,nps400-timer0":
+- interrupts : The interrupt of the first timer
+- clocks : Must contain a single entry describing the clock input
+
+Example:
+
+timer {
+ compatible = "ezchip,nps400-timer0";
+ interrupts = <3>;
+ clocks = <&sysclk>;
+};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
index c8c03d700382..c0ab4190b8fb 100644
--- a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
@@ -2,14 +2,14 @@ NPS Network Processor
Required properties:
-- compatible : should be "ezchip,nps400-timer"
+- compatible : should be "ezchip,nps400-timer1"
-Clocks required for compatible = "ezchip,nps400-timer":
+Clocks required for compatible = "ezchip,nps400-timer1":
- clocks : Must contain a single entry describing the clock input
Example:
timer {
- compatible = "ezchip,nps400-timer";
+ compatible = "ezchip,nps400-timer1";
clocks = <&sysclk>;
};
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
index f4262ed60582..ad8ea56a9ed3 100644
--- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
+++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
@@ -6,9 +6,9 @@ Required properties:
- compatible: Should be "atmel,at91rm9200-ohci" for USB controllers
used in host mode.
- reg: Address and length of the register set for the device
- - interrupts: Should contain ehci interrupt
+ - interrupts: Should contain ohci interrupt
- clocks: Should reference the peripheral, host and system clocks
- - clock-names: Should contains two strings
+ - clock-names: Should contain three strings
"ohci_clk" for the peripheral clock
"hclk" for the host clock
"uhpck" for the system clock
@@ -35,7 +35,7 @@ Required properties:
- reg: Address and length of the register set for the device
- interrupts: Should contain ehci interrupt
- clocks: Should reference the peripheral and the UTMI clocks
- - clock-names: Should contains two strings
+ - clock-names: Should contain two strings
"ehci_clk" for the peripheral clock
"usb_clk" for the UTMI clock
@@ -58,7 +58,7 @@ Required properties:
- reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt
- clocks: Should reference the peripheral and the AHB clocks
- - clock-names: Should contains two strings
+ - clock-names: Should contain two strings
"pclk" for the peripheral clock
"hclk" for the AHB clock
@@ -85,7 +85,7 @@ Required properties:
- reg: Address and length of the register set for the device
- interrupts: Should contain usba interrupt
- clocks: Should reference the peripheral and host clocks
- - clock-names: Should contains two strings
+ - clock-names: Should contain two strings
"pclk" for the peripheral clock
"hclk" for the host clock
- ep childnode: To specify the number of endpoints and their properties.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 078834a5fd85..16d3b5e7f5d1 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -24,9 +24,11 @@ ampire Ampire Co., Ltd.
ams AMS AG
amstaos AMS-Taos Inc.
analogix Analogix Semiconductor, Inc.
+andestech Andes Technology Corporation
apm Applied Micro Circuits Corporation (APM)
aptina Aptina Imaging
arasan Arasan Chip Systems
+aries Aries Embedded GmbH
arm ARM Ltd.
armadeus ARMadeus Systems SARL
arrow Arrow Electronics
@@ -68,6 +70,7 @@ creative Creative Technology Ltd
crystalfontz Crystalfontz America, Inc.
cubietech Cubietech, Ltd.
cypress Cypress Semiconductor Corporation
+cznic CZ.NIC, z.s.p.o.
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
@@ -161,6 +164,7 @@ lg LG Corporation
linux Linux-specific binding
lltc Linear Technology Corporation
lsi LSI Corp. (LSI Logic)
+macnica Macnica Americas
marvell Marvell Technology Group Ltd.
maxim Maxim Integrated Products
mcube mCube
@@ -186,20 +190,24 @@ mti Imagination Technologies Ltd. (formerly MIPS Technologies Inc.)
mundoreader Mundo Reader S.L.
murata Murata Manufacturing Co., Ltd.
mxicy Macronix International Co., Ltd.
+myir MYIR Tech Limited
national National Semiconductor
nec NEC LCD Technologies, Ltd.
neonode Neonode Inc.
netgear NETGEAR
netlogic Broadcom Corporation (formerly NetLogic Microsystems)
netxeon Shenzhen Netxeon Technology CO., LTD
+nexbox Nexbox
newhaven Newhaven Display International
-nvd New Vision Display
+ni National Instruments
nintendo Nintendo
nokia Nokia
nuvoton Nuvoton Technology Corporation
+nvd New Vision Display
nvidia NVIDIA
nxp NXP Semiconductors
okaya Okaya Electric America, Inc.
+oki Oki Electric Industry Co., Ltd.
olimex OLIMEX Ltd.
onion Onion Corporation
onnn ON Semiconductor Corp.
@@ -215,6 +223,7 @@ parade Parade Technologies Inc.
pericom Pericom Technology Inc.
phytec PHYTEC Messtechnik GmbH
picochip Picochip Ltd
+pine64 Pine64
pixcir PIXCIR MICROELECTRONICS Co., Ltd
plathome Plat'Home Co., Ltd.
plda PLDA
@@ -236,8 +245,10 @@ realtek Realtek Semiconductor Corp.
renesas Renesas Electronics Corporation
richtek Richtek Technology Corporation
ricoh Ricoh Co. Ltd.
+rikomagic Rikomagic Tech Corp. Ltd
rockchip Fuzhou Rockchip Electronics Co., Ltd
samsung Samsung Semiconductor
+samtec Samtec/Softing company
sandisk Sandisk Corporation
sbs Smart Battery System
schindler Schindler
@@ -282,6 +293,7 @@ tcg Trusted Computing Group
tcl Toby Churchill Ltd.
technexion TechNexion
technologic Technologic Systems
+terasic Terasic Inc.
thine THine Electronics, Inc.
ti Texas Instruments
tlm Trusted Logic Mobility
@@ -296,6 +308,7 @@ tronfy Tronfy
tronsmart Tronsmart
truly Truly Semiconductors Limited
tyan Tyan Computer Corporation
+udoo Udoo
uniwest United Western Technologies Corp (UniWest)
upisemi uPI Semiconductor Corp.
urt United Radiant Technology Corporation
diff --git a/Documentation/dmaengine/client.txt b/Documentation/dmaengine/client.txt
index 9e33189745f0..c72b4563de10 100644
--- a/Documentation/dmaengine/client.txt
+++ b/Documentation/dmaengine/client.txt
@@ -37,8 +37,8 @@ The slave DMA usage consists of following steps:
2. Set slave and controller specific parameters
Next step is always to pass some specific information to the DMA
- driver. Most of the generic information which a slave DMA can use
- is in struct dma_slave_config. This allows the clients to specify
+ driver. Most of the generic information which a slave DMA can use
+ is in struct dma_slave_config. This allows the clients to specify
DMA direction, DMA addresses, bus widths, DMA burst lengths etc
for the peripheral.
@@ -52,7 +52,7 @@ The slave DMA usage consists of following steps:
struct dma_slave_config *config)
Please see the dma_slave_config structure definition in dmaengine.h
- for a detailed explanation of the struct members. Please note
+ for a detailed explanation of the struct members. Please note
that the 'direction' member will be going away as it duplicates the
direction given in the prepare call.
@@ -101,7 +101,7 @@ The slave DMA usage consists of following steps:
desc = dmaengine_prep_slave_sg(chan, sgl, nr_sg, direction, flags);
Once a descriptor has been obtained, the callback information can be
- added and the descriptor must then be submitted. Some DMA engine
+ added and the descriptor must then be submitted. Some DMA engine
drivers may hold a spinlock between a successful preparation and
submission so it is important that these two operations are closely
paired.
@@ -138,7 +138,7 @@ The slave DMA usage consists of following steps:
activity via other DMA engine calls not covered in this document.
dmaengine_submit() will not start the DMA operation, it merely adds
- it to the pending queue. For this, see step 5, dma_async_issue_pending.
+ it to the pending queue. For this, see step 5, dma_async_issue_pending.
5. Issue pending DMA requests and wait for callback notification
@@ -184,13 +184,13 @@ Further APIs:
3. int dmaengine_resume(struct dma_chan *chan)
- Resume a previously paused DMA channel. It is invalid to resume a
+ Resume a previously paused DMA channel. It is invalid to resume a
channel which is not currently paused.
4. enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
- This can be used to check the status of the channel. Please see
+ This can be used to check the status of the channel. Please see
the documentation in include/linux/dmaengine.h for a more complete
description of this API.
@@ -200,7 +200,7 @@ Further APIs:
Note:
Not all DMA engine drivers can return reliable information for
- a running DMA channel. It is recommended that DMA engine users
+ a running DMA channel. It is recommended that DMA engine users
pause or stop (via dmaengine_terminate_all()) the channel before
using this API.
diff --git a/Documentation/dmaengine/dmatest.txt b/Documentation/dmaengine/dmatest.txt
index dd77a81bdb80..fb683c72dea8 100644
--- a/Documentation/dmaengine/dmatest.txt
+++ b/Documentation/dmaengine/dmatest.txt
@@ -34,7 +34,7 @@ command:
% ls -1 /sys/class/dma/
Once started a message like "dmatest: Started 1 threads using dma0chan0" is
-emitted. After that only test failure messages are reported until the test
+emitted. After that only test failure messages are reported until the test
stops.
Note that running a new test will not stop any in progress test.
@@ -43,11 +43,11 @@ The following command returns the state of the test.
% cat /sys/module/dmatest/parameters/run
To wait for test completion userpace can poll 'run' until it is false, or use
-the wait parameter. Specifying 'wait=1' when loading the module causes module
+the wait parameter. Specifying 'wait=1' when loading the module causes module
initialization to pause until a test run has completed, while reading
/sys/module/dmatest/parameters/wait waits for any running test to complete
-before returning. For example, the following scripts wait for 42 tests
-to complete before exiting. Note that if 'iterations' is set to 'infinite' then
+before returning. For example, the following scripts wait for 42 tests
+to complete before exiting. Note that if 'iterations' is set to 'infinite' then
waiting is disabled.
Example:
@@ -81,7 +81,7 @@ Example of output:
The message format is unified across the different types of errors. A number in
the parens represents additional information, e.g. error code, error counter,
-or status. A test thread also emits a summary line at completion listing the
+or status. A test thread also emits a summary line at completion listing the
number of tests executed, number that failed, and a result code.
Example:
diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt
index c4fd47540b31..e33bc1c8ed2c 100644
--- a/Documentation/dmaengine/provider.txt
+++ b/Documentation/dmaengine/provider.txt
@@ -384,7 +384,7 @@ where to put them)
- The descriptor should be prepared for reuse by invoking
dmaengine_desc_set_reuse() which will set DMA_CTRL_REUSE.
- dmaengine_desc_set_reuse() will succeed only when channel support
- reusable descriptor as exhibited by capablities
+ reusable descriptor as exhibited by capabilities
- As a consequence, if a device driver wants to skip the dma_map_sg() and
dma_unmap_sg() in between 2 transfers, because the DMA'd data wasn't used,
it can resubmit the transfer right after its completion.
diff --git a/Documentation/dmaengine/pxa_dma.txt b/Documentation/dmaengine/pxa_dma.txt
index 413ef9cfaa4d..0736d44b5438 100644
--- a/Documentation/dmaengine/pxa_dma.txt
+++ b/Documentation/dmaengine/pxa_dma.txt
@@ -29,7 +29,7 @@ Constraints
d) Bandwidth guarantee
The PXA architecture has 4 levels of DMAs priorities : high, normal, low.
- The high prorities get twice as much bandwidth as the normal, which get twice
+ The high priorities get twice as much bandwidth as the normal, which get twice
as much as the low priorities.
A driver should be able to request a priority, especially the real-time
ones such as pxa_camera with (big) throughputs.
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index 74eaac26f8b8..6ea1ceda6f52 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -17,6 +17,7 @@ that support it. For example, a given bus might look like this:
| |-- resource0
| |-- resource1
| |-- resource2
+ | |-- revision
| |-- rom
| |-- subsystem_device
| |-- subsystem_vendor
@@ -41,6 +42,7 @@ files, each with their own function.
resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap, rw[1])
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
+ revision PCI revision (ascii, ro)
rom PCI ROM resource, if present (binary, ro)
subsystem_device PCI subsystem device (ascii, ro)
subsystem_vendor PCI subsystem vendor (ascii, ro)
diff --git a/Documentation/filesystems/xfs.txt b/Documentation/filesystems/xfs.txt
index c2d44e6e117b..3b9b5c149f32 100644
--- a/Documentation/filesystems/xfs.txt
+++ b/Documentation/filesystems/xfs.txt
@@ -51,13 +51,6 @@ default behaviour.
CRC enabled filesystems always use the attr2 format, and so
will reject the noattr2 mount option if it is set.
- barrier (*)
- nobarrier
- Enables/disables the use of block layer write barriers for
- writes into the journal and for data integrity operations.
- This allows for drive level write caching to be enabled, for
- devices that support write barriers.
-
discard
nodiscard (*)
Enable/disable the issuing of commands to let the block
@@ -228,7 +221,10 @@ default behaviour.
Deprecated Mount Options
========================
-None at present.
+ Name Removal Schedule
+ ---- ----------------
+ barrier no earlier than v4.15
+ nobarrier no earlier than v4.15
Removed Mount Options
diff --git a/Documentation/i2c/busses/i2c-mlxcpld b/Documentation/i2c/busses/i2c-mlxcpld
new file mode 100644
index 000000000000..4e46c440b38d
--- /dev/null
+++ b/Documentation/i2c/busses/i2c-mlxcpld
@@ -0,0 +1,47 @@
+Driver i2c-mlxcpld
+
+Author: Michael Shych <michaelsh@mellanox.com>
+
+This is the Mellanox I2C controller logic, implemented in Lattice CPLD
+device.
+Device supports:
+ - Master mode.
+ - One physical bus.
+ - Polling mode.
+
+This controller is equipped within the next Mellanox systems:
+"msx6710", "msx6720", "msb7700", "msn2700", "msx1410", "msn2410", "msb7800",
+"msn2740", "msn2100".
+
+The next transaction types are supported:
+ - Receive Byte/Block.
+ - Send Byte/Block.
+ - Read Byte/Block.
+ - Write Byte/Block.
+
+Registers:
+CTRL 0x1 - control reg.
+ Resets all the registers.
+HALF_CYC 0x4 - cycle reg.
+ Configure the width of I2C SCL half clock cycle (in 4 LPC_CLK
+ units).
+I2C_HOLD 0x5 - hold reg.
+ OE (output enable) is delayed by value set to this register
+ (in LPC_CLK units)
+CMD 0x6 - command reg.
+ Bit 0, 0 = write, 1 = read.
+ Bits [7:1] - the 7bit Address of the I2C device.
+ It should be written last as it triggers an I2C transaction.
+NUM_DATA 0x7 - data size reg.
+ Number of data bytes to write in read transaction
+NUM_ADDR 0x8 - address reg.
+ Number of address bytes to write in read transaction.
+STATUS 0x9 - status reg.
+ Bit 0 - transaction is completed.
+ Bit 4 - ACK/NACK.
+DATAx 0xa - 0x54 - 68 bytes data buffer regs.
+ For write transaction address is specified in four first bytes
+ (DATA1 - DATA4), data starting from DATA4.
+ For read transactions address is sent in a separate transaction and
+ specified in the four first bytes (DATA0 - DATA3). Data is read
+ starting from DATA0.
diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol
index 14d4ec1be245..092d474f5843 100644
--- a/Documentation/i2c/smbus-protocol
+++ b/Documentation/i2c/smbus-protocol
@@ -200,10 +200,14 @@ alerting device's address.
[S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P]
This is implemented in the following way in the Linux kernel:
-* I2C bus drivers which support SMBus Host Notify should call
- i2c_setup_smbus_host_notify() to setup SMBus Host Notify support.
-* I2C drivers for devices which can trigger SMBus Host Notify should implement
- the optional alert() callback.
+* I2C bus drivers which support SMBus Host Notify should report
+ I2C_FUNC_SMBUS_HOST_NOTIFY.
+* I2C bus drivers trigger SMBus Host Notify by a call to
+ i2c_handle_smbus_host_notify().
+* I2C drivers for devices which can trigger SMBus Host Notify will have
+ client->irq assigned to a Host Notify IRQ if noone else specified an other.
+
+There is currently no way to retrieve the data parameter from the client.
Packet Error Checking (PEC)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 72a150d8f3df..ba2e7d254842 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -540,6 +540,7 @@ Events that are propagated by the driver to userspace:
0x6022 ALARM: a sensor is extremely hot
0x6030 System thermal table changed
0x6040 Nvidia Optimus/AC adapter related (TO BE VERIFIED)
+0x60C0 X1 Yoga 2016, Tablet mode status changed
Battery nearly empty alarms are a last resort attempt to get the
operating system to hibernate or shutdown cleanly (0x2313), or shutdown
diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt
index 08d74d75150d..2cc08d4a326e 100644
--- a/Documentation/trace/events.txt
+++ b/Documentation/trace/events.txt
@@ -189,16 +189,13 @@ And for string fields they are:
==, !=, ~
-The glob (~) only accepts a wild card character (*) at the start and or
-end of the string. For example:
+The glob (~) accepts a wild card character (*,?) and character classes
+([). For example:
prev_comm ~ "*sh"
prev_comm ~ "sh*"
prev_comm ~ "*sh*"
-
-But does not allow for it to be within the string:
-
- prev_comm ~ "ba*sh" <-- is invalid
+ prev_comm ~ "ba*sh"
5.2 Setting filters
-------------------
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index 5596e2d71d6d..006f47c7d913 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -416,6 +416,12 @@ of ftrace. Here is a list of some of the key files:
trace_fd = open("trace_marker", WR_ONLY);
+ trace_marker_raw:
+
+ This is similar to trace_marker above, but is meant for for binary data
+ to be written to it, where a tool can be used to parse the data
+ from trace_pipe_raw.
+
uprobe_events:
Add dynamic tracepoints in programs.
@@ -2238,16 +2244,13 @@ hrtimer_interrupt
sys_nanosleep
-Perhaps this is not enough. The filters also allow simple wild
-cards. Only the following are currently available
+Perhaps this is not enough. The filters also allow glob(7) matching.
<match>* - will match functions that begin with <match>
*<match> - will match functions that end with <match>
*<match>* - will match functions that have <match> in it
-
-These are the only wild cards which are supported.
-
- <match>*<match> will not work.
+ <match1>*<match2> - will match functions that begin with
+ <match1> and end with <match2>
Note: It is better to use quotes to enclose the wild cards,
otherwise the shell may expand the parameters into names
diff --git a/MAINTAINERS b/MAINTAINERS
index 650ad4f6b608..299ee500f8fd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -540,6 +540,7 @@ S: Supported
F: fs/afs/
F: include/net/af_rxrpc.h
F: net/rxrpc/af_rxrpc.c
+W: https://www.infradead.org/~dhowells/kafs/
AGPGART DRIVER
M: David Airlie <airlied@linux.ie>
@@ -1041,6 +1042,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
N: sun[x456789]i
F: arch/arm/boot/dts/ntc-gr8*
+F: arch/arm64/boot/dts/allwinner/
ARM/Allwinner SoC Clock Support
M: Emilio López <emilio@elopez.com.ar>
@@ -1502,8 +1504,9 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-oxnas@lists.tuxfamily.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-oxnas/
-F: arch/arm/boot/dts/oxnas*
+F: arch/arm/boot/dts/ox8*.dtsi
F: arch/arm/boot/dts/wd-mbwe.dts
+F: arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
N: oxnas
ARM/Mediatek RTC DRIVER
@@ -1624,6 +1627,7 @@ F: arch/arm/mach-qcom/
F: arch/arm64/boot/dts/qcom/*
F: drivers/i2c/busses/i2c-qup.c
F: drivers/clk/qcom/
+F: drivers/pinctrl/qcom/
F: drivers/soc/qcom/
F: drivers/spi/spi-qup.c
F: drivers/tty/serial/msm_serial.h
@@ -1804,9 +1808,7 @@ F: drivers/media/rc/st_rc.c
F: drivers/media/platform/sti/c8sectpfe/
F: drivers/mmc/host/sdhci-st.c
F: drivers/phy/phy-miphy28lp.c
-F: drivers/phy/phy-miphy365x.c
F: drivers/phy/phy-stih407-usb.c
-F: drivers/phy/phy-stih41x-usb.c
F: drivers/pinctrl/pinctrl-st.c
F: drivers/remoteproc/st_remoteproc.c
F: drivers/remoteproc/st_slim_rproc.c
@@ -2800,7 +2802,7 @@ S: Supported
F: drivers/net/ethernet/broadcom/bcmsysport.*
BROADCOM VULCAN ARM64 SOC
-M: Jayachandran C. <jchandra@broadcom.com>
+M: Jayachandran C. <c.jayachandran@gmail.com>
M: bcm-kernel-feedback-list@broadcom.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
@@ -6514,10 +6516,7 @@ F: drivers/net/ethernet/intel/*/
INTEL RDMA RNIC DRIVER
M: Faisal Latif <faisal.latif@intel.com>
-R: Chien Tin Tung <chien.tin.tung@intel.com>
-R: Mustafa Ismail <mustafa.ismail@intel.com>
-R: Shiraz Saleem <shiraz.saleem@intel.com>
-R: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
+M: Shiraz Saleem <shiraz.saleem@intel.com>
L: linux-rdma@vger.kernel.org
S: Supported
F: drivers/infiniband/hw/i40iw/
@@ -8025,6 +8024,15 @@ W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlxsw/
+MELLANOX MLXCPLD I2C AND MUX DRIVER
+M: Vadim Pasternak <vadimp@mellanox.com>
+M: Michael Shych <michaelsh@mellanox.com>
+L: linux-i2c@vger.kernel.org
+S: Supported
+F: drivers/i2c/busses/i2c-mlxcpld.c
+F: drivers/i2c/muxes/i2c-mux-mlxcpld.c
+F: Documentation/i2c/busses/i2c-mlxcpld
+
MELLANOX MLXCPLD LED DRIVER
M: Vadim Pasternak <vadimp@mellanox.com>
L: linux-leds@vger.kernel.org
@@ -8038,6 +8046,13 @@ L: platform-driver-x86@vger.kernel.org
S: Supported
F: arch/x86/platform/mellanox/mlx-platform.c
+MELLANOX MLX CPLD HOTPLUG DRIVER
+M: Vadim Pasternak <vadimp@mellanox.com>
+L: platform-driver-x86@vger.kernel.org
+S: Supported
+F: drivers/platform/x86/mlxcpld-hotplug.c
+F: include/linux/platform_data/mlxcpld-hotplug.h
+
SOFT-ROCE DRIVER (rxe)
M: Moni Shoua <monis@mellanox.com>
L: linux-rdma@vger.kernel.org
@@ -11077,7 +11092,6 @@ F: drivers/net/ethernet/emulex/benet/
EMULEX ONECONNECT ROCE DRIVER
M: Selvin Xavier <selvin.xavier@avagotech.com>
M: Devesh Sharma <devesh.sharma@avagotech.com>
-M: Mitesh Ahuja <mitesh.ahuja@avagotech.com>
L: linux-rdma@vger.kernel.org
W: http://www.emulex.com
S: Supported
@@ -11814,6 +11828,7 @@ S: Supported
F: arch/arc/
F: Documentation/devicetree/bindings/arc/*
F: Documentation/devicetree/bindings/interrupt-controller/snps,arc*
+F: drivers/clocksource/arc_timer.c
F: drivers/tty/serial/arc_uart.c
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
@@ -12074,6 +12089,16 @@ S: Maintained
F: arch/xtensa/
F: drivers/irqchip/irq-xtensa-*
+Texas Instruments' System Control Interface (TISCI) Protocol Driver
+M: Nishanth Menon <nm@ti.com>
+M: Tero Kristo <t-kristo@ti.com>
+M: Santosh Shilimkar <ssantosh@kernel.org>
+L: linux-arm-kernel@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+F: drivers/firmware/ti_sci*
+F: include/linux/soc/ti/ti_sci_protocol.h
+
THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -13137,6 +13162,13 @@ S: Maintained
F: drivers/scsi/vmw_pvscsi.c
F: drivers/scsi/vmw_pvscsi.h
+VMWARE PVRDMA DRIVER
+M: Adit Ranadive <aditr@vmware.com>
+M: VMware PV-Drivers <pv-drivers@vmware.com>
+L: linux-rdma@vger.kernel.org
+S: Maintained
+F: drivers/infiniband/hw/vmw_pvrdma/
+
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
M: Liam Girdwood <lgirdwood@gmail.com>
M: Mark Brown <broonie@kernel.org>
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index bd204bfa29ed..ab12723d39a0 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -8,9 +8,9 @@
config ARC
def_bool y
+ select ARC_TIMERS
select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
select BUILDTIME_EXTABLE_SORT
- select CLKSRC_OF
select CLONE_BACKWARDS
select COMMON_CLK
select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
@@ -115,6 +115,7 @@ config ISA_ARCOMPACT
config ISA_ARCV2
bool "ARC ISA v2"
+ select ARC_TIMERS_64BIT
help
ISA for the Next Generation ARC-HS cores
@@ -410,16 +411,6 @@ config ARC_HAS_DIV_REM
bool "Insn: div, divu, rem, remu"
default y
-config ARC_HAS_RTC
- bool "Local 64-bit r/o cycle counter"
- default n
- depends on !SMP
-
-config ARC_HAS_GFRC
- bool "SMP synchronized 64-bit cycle counter"
- default y
- depends on SMP
-
config ARC_NUMBER_OF_INTERRUPTS
int "Number of interrupts"
range 8 240
diff --git a/arch/arc/boot/dts/abilis_tb10x.dtsi b/arch/arc/boot/dts/abilis_tb10x.dtsi
index de53f5c3251c..3121536b25a3 100644
--- a/arch/arc/boot/dts/abilis_tb10x.dtsi
+++ b/arch/arc/boot/dts/abilis_tb10x.dtsi
@@ -129,6 +129,7 @@
data-width = <4>;
clocks = <&ahb_clk>;
clock-names = "hclk";
+ multi-block = <1 1 1 1 1 1>;
};
i2c0: i2c@FF120000 {
diff --git a/arch/arc/boot/dts/axs101.dts b/arch/arc/boot/dts/axs101.dts
index d9b9b9dcfc4c..70aec7d6ca60 100644
--- a/arch/arc/boot/dts/axs101.dts
+++ b/arch/arc/boot/dts/axs101.dts
@@ -17,6 +17,6 @@
compatible = "snps,axs101", "snps,arc-sdp";
chosen {
- bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0";
+ bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 video=1280x720@60";
};
};
diff --git a/arch/arc/boot/dts/axs103_idu.dts b/arch/arc/boot/dts/axs103_idu.dts
index 070c29782216..5c843d9b4ac8 100644
--- a/arch/arc/boot/dts/axs103_idu.dts
+++ b/arch/arc/boot/dts/axs103_idu.dts
@@ -20,6 +20,6 @@
compatible = "snps,axs103", "snps,arc-sdp";
chosen {
- bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=ttyS3,115200n8 debug print-fatal-signals=1";
+ bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 print-fatal-signals=1 consoleblank=0 video=1280x720@60";
};
};
diff --git a/arch/arc/boot/dts/zebu_hs.dts b/arch/arc/boot/dts/haps_hs.dts
index 1c1324e84965..1c1324e84965 100644
--- a/arch/arc/boot/dts/zebu_hs.dts
+++ b/arch/arc/boot/dts/haps_hs.dts
diff --git a/arch/arc/boot/dts/zebu_hs_idu.dts b/arch/arc/boot/dts/haps_hs_idu.dts
index 65204b4c0f13..65204b4c0f13 100644
--- a/arch/arc/boot/dts/zebu_hs_idu.dts
+++ b/arch/arc/boot/dts/haps_hs_idu.dts
diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 0a0eaf09aac7..6980b966a364 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -75,9 +75,11 @@ CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
# CONFIG_HWMON is not set
+CONFIG_DRM=m
+CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_ARCPGU=m
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index 110874705085..30a3d4cf53d2 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -77,9 +77,11 @@ CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
# CONFIG_HWMON is not set
+CONFIG_DRM=m
+CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_ARCPGU=m
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
diff --git a/arch/arc/configs/zebu_hs_defconfig b/arch/arc/configs/haps_hs_defconfig
index 9f6166be7145..57b3e599322f 100644
--- a/arch/arc/configs/zebu_hs_defconfig
+++ b/arch/arc/configs/haps_hs_defconfig
@@ -23,7 +23,7 @@ CONFIG_MODULES=y
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_SIM=y
CONFIG_ISA_ARCV2=y
-CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs"
+CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
CONFIG_NET=y
diff --git a/arch/arc/configs/zebu_hs_smp_defconfig b/arch/arc/configs/haps_hs_smp_defconfig
index 44e9693f4257..f85985adebb2 100644
--- a/arch/arc/configs/zebu_hs_smp_defconfig
+++ b/arch/arc/configs/haps_hs_smp_defconfig
@@ -26,7 +26,7 @@ CONFIG_MODULES=y
CONFIG_ARC_PLAT_SIM=y
CONFIG_ISA_ARCV2=y
CONFIG_SMP=y
-CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs_idu"
+CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
CONFIG_NET=y
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index 6da71ba253a9..155add7761ed 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -21,7 +21,7 @@ CONFIG_MODULES=y
CONFIG_ARC_PLAT_SIM=y
CONFIG_ISA_ARCV2=y
CONFIG_SMP=y
-# CONFIG_ARC_HAS_GFRC is not set
+# CONFIG_ARC_TIMERS_64BIT is not set
CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig
index 969b206d6c67..573028f19de7 100644
--- a/arch/arc/configs/vdk_hs38_smp_defconfig
+++ b/arch/arc/configs/vdk_hs38_smp_defconfig
@@ -15,7 +15,7 @@ CONFIG_ARC_PLAT_AXS10X=y
CONFIG_AXS103=y
CONFIG_ISA_ARCV2=y
CONFIG_SMP=y
-# CONFIG_ARC_HAS_GFRC is not set
+# CONFIG_ARC_TIMERS_64BIT is not set
CONFIG_ARC_UBOOT_SUPPORT=y
CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
CONFIG_PREEMPT=y
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 1bd24ec3e350..da41a54ea2d7 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -20,7 +20,6 @@
#define ARC_REG_FP_V2_BCR 0xc8 /* ARCv2 FPU */
#define ARC_REG_SLC_BCR 0xce
#define ARC_REG_DCCM_BUILD 0x74 /* DCCM size (common) */
-#define ARC_REG_TIMERS_BCR 0x75
#define ARC_REG_AP_BCR 0x76
#define ARC_REG_ICCM_BUILD 0x78 /* ICCM size (common) */
#define ARC_REG_XY_MEM_BCR 0x79
@@ -112,90 +111,7 @@
#ifndef __ASSEMBLY__
-/*
- ******************************************************************
- * Inline ASM macros to read/write AUX Regs
- * Essentially invocation of lr/sr insns from "C"
- */
-
-#if 1
-
-#define read_aux_reg(reg) __builtin_arc_lr(reg)
-
-/* gcc builtin sr needs reg param to be long immediate */
-#define write_aux_reg(reg_immed, val) \
- __builtin_arc_sr((unsigned int)(val), reg_immed)
-
-#else
-
-#define read_aux_reg(reg) \
-({ \
- unsigned int __ret; \
- __asm__ __volatile__( \
- " lr %0, [%1]" \
- : "=r"(__ret) \
- : "i"(reg)); \
- __ret; \
-})
-
-/*
- * Aux Reg address is specified as long immediate by caller
- * e.g.
- * write_aux_reg(0x69, some_val);
- * This generates tightest code.
- */
-#define write_aux_reg(reg_imm, val) \
-({ \
- __asm__ __volatile__( \
- " sr %0, [%1] \n" \
- : \
- : "ir"(val), "i"(reg_imm)); \
-})
-
-/*
- * Aux Reg address is specified in a variable
- * * e.g.
- * reg_num = 0x69
- * write_aux_reg2(reg_num, some_val);
- * This has to generate glue code to load the reg num from
- * memory to a reg hence not recommended.
- */
-#define write_aux_reg2(reg_in_var, val) \
-({ \
- unsigned int tmp; \
- \
- __asm__ __volatile__( \
- " ld %0, [%2] \n\t" \
- " sr %1, [%0] \n\t" \
- : "=&r"(tmp) \
- : "r"(val), "memory"(&reg_in_var)); \
-})
-
-#endif
-
-#define READ_BCR(reg, into) \
-{ \
- unsigned int tmp; \
- tmp = read_aux_reg(reg); \
- if (sizeof(tmp) == sizeof(into)) { \
- into = *((typeof(into) *)&tmp); \
- } else { \
- extern void bogus_undefined(void); \
- bogus_undefined(); \
- } \
-}
-
-#define WRITE_AUX(reg, into) \
-{ \
- unsigned int tmp; \
- if (sizeof(tmp) == sizeof(into)) { \
- tmp = (*(unsigned int *)&(into)); \
- write_aux_reg(reg, tmp); \
- } else { \
- extern void bogus_undefined(void); \
- bogus_undefined(); \
- } \
-}
+#include <soc/arc/aux.h>
/* Helpers */
#define TO_KB(bytes) ((bytes) >> 10)
@@ -291,13 +207,7 @@ struct bcr_fp_arcv2 {
#endif
};
-struct bcr_timer {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
-#else
- unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
-#endif
-};
+#include <soc/arc/timers.h>
struct bcr_bpu_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index cfcdedf52ff8..8942c5c3b4c5 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -8,7 +8,7 @@
# Pass UTS_MACHINE for user_regset definition
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
-obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
+obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o
obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index f39142acc89e..560c4afc2af4 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -11,8 +11,8 @@
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
+#include <soc/arc/mcip.h>
#include <asm/irqflags-arcv2.h>
-#include <asm/mcip.h>
#include <asm/setup.h>
static DEFINE_RAW_SPINLOCK(mcip_lock);
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 0385df77a697..3093fa898a23 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -10,6 +10,8 @@
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/root_dev.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
#include <linux/console.h>
#include <linux/module.h>
#include <linux/cpu.h>
@@ -234,11 +236,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
is_isa_arcompact() ? "ARCompact" : "ARCv2",
IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
- n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
+ n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
- IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
- CONFIG_ARC_HAS_RTC));
+ IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT),
+ IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT));
n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
@@ -449,6 +451,15 @@ void __init setup_arch(char **cmdline_p)
arc_unwind_init();
}
+/*
+ * Called from start_kernel() - boot CPU only
+ */
+void __init time_init(void)
+{
+ of_clk_init(NULL);
+ clocksource_probe();
+}
+
static int __init customize_machine(void)
{
if (machine_desc->init_machine)
diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
index 86548701023c..38ff349d7f2a 100644
--- a/arch/arc/plat-axs10x/axs10x.c
+++ b/arch/arc/plat-axs10x/axs10x.c
@@ -21,7 +21,7 @@
#include <asm/asm-offsets.h>
#include <asm/io.h>
#include <asm/mach_desc.h>
-#include <asm/mcip.h>
+#include <soc/arc/mcip.h>
#define AXS_MB_CGU 0xE0010000
#define AXS_MB_CREG 0xE0011000
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
index 9d6718c1a199..ee2e32df5e90 100644
--- a/arch/arc/plat-eznps/include/plat/ctop.h
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -46,9 +46,7 @@
#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300)
/* EZchip core instructions */
-#define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF
#define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF
-#define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3
#define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103
#define CTOP_INST_SCHD_RW 0x3E6F7004
#define CTOP_INST_SCHD_RD 0x3E6F7084
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index caef68429b08..5fab553fd03a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -888,6 +888,11 @@ config MACH_STM32F429
depends on ARCH_STM32
default y
+config MACH_STM32F746
+ bool "STMicrolectronics STM32F746"
+ depends on ARCH_STM32
+ default y
+
config ARCH_MPS2
bool "ARM MPS2 platform"
depends on ARM_SINGLE_ARMV7M
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6be9ee148b78..ab30cc634d02 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -191,6 +191,7 @@ machine-$(CONFIG_ARCH_MXS) += mxs
machine-$(CONFIG_ARCH_NETX) += netx
machine-$(CONFIG_ARCH_NOMADIK) += nomadik
machine-$(CONFIG_ARCH_NSPIRE) += nspire
+machine-$(CONFIG_ARCH_OXNAS) += oxnas
machine-$(CONFIG_ARCH_OMAP1) += omap1
machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
machine-$(CONFIG_ARCH_ORION5X) += orion5x
@@ -311,8 +312,11 @@ all: $(KBUILD_IMAGE) $(KBUILD_DTBS)
boot := arch/arm/boot
+archheaders:
+ $(Q)$(MAKE) $(build)=arch/arm/tools uapi
+
archprepare:
- $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
+ $(Q)$(MAKE) $(build)=arch/arm/tools kapi
# Convert bzImage to zImage
bzImage: zImage
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index c558ba75cbcc..cccdbcb557b6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -75,6 +75,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm4708-asus-rt-ac56u.dtb \
bcm4708-asus-rt-ac68u.dtb \
bcm4708-buffalo-wzr-1750dhp.dtb \
+ bcm4708-luxul-xap-1510.dtb \
bcm4708-luxul-xwc-1000.dtb \
bcm4708-netgear-r6250.dtb \
bcm4708-netgear-r6300-v2.dtb \
@@ -86,11 +87,16 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm4709-buffalo-wxr-1900dhp.dtb \
bcm4709-netgear-r7000.dtb \
bcm4709-netgear-r8000.dtb \
+ bcm4709-tplink-archer-c9-v1.dtb \
bcm47094-dlink-dir-885l.dtb \
+ bcm47094-luxul-xwr-3100.dtb \
+ bcm47094-netgear-r8500.dtb \
bcm94708.dtb \
bcm94709.dtb \
bcm953012er.dtb \
bcm953012k.dtb
+dtb-$(CONFIG_ARCH_BCM_53573) += \
+ bcm47189-tenda-ac9.dtb
dtb-$(CONFIG_ARCH_BCM_63XX) += \
bcm963138dvt.dtb
dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
@@ -136,6 +142,7 @@ dtb-$(CONFIG_ARCH_EXYNOS4) += \
exynos4210-smdkv310.dtb \
exynos4210-trats.dtb \
exynos4210-universal_c210.dtb \
+ exynos4412-itop-elite.dtb \
exynos4412-odroidu3.dtb \
exynos4412-odroidx.dtb \
exynos4412-odroidx2.dtb \
@@ -330,6 +337,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-aristainetos_7.dtb \
imx6dl-aristainetos2_4.dtb \
imx6dl-aristainetos2_7.dtb \
+ imx6dl-colibri-eval-v3.dtb \
imx6dl-cubox-i.dtb \
imx6dl-dfi-fs700-m60.dtb \
imx6dl-gw51xx.dtb \
@@ -340,6 +348,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-gw552x.dtb \
imx6dl-gw553x.dtb \
imx6dl-hummingboard.dtb \
+ imx6dl-icore.dtb \
imx6dl-nit6xlite.dtb \
imx6dl-nitrogen6x.dtb \
imx6dl-phytec-pbab01.dtb \
@@ -381,10 +390,12 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-gw553x.dtb \
imx6q-h100.dtb \
imx6q-hummingboard.dtb \
+ imx6q-icore.dtb \
imx6q-icore-rqs.dtb \
imx6q-marsboard.dtb \
imx6q-nitrogen6x.dtb \
imx6q-nitrogen6_max.dtb \
+ imx6q-nitrogen6_som2.dtb \
imx6q-novena.dtb \
imx6q-phytec-pbab01.dtb \
imx6q-rex-pro.dtb \
@@ -416,14 +427,19 @@ dtb-$(CONFIG_SOC_IMX6SX) += \
imx6sx-sabreauto.dtb \
imx6sx-sdb-reva.dtb \
imx6sx-sdb-sai.dtb \
- imx6sx-sdb.dtb
+ imx6sx-sdb.dtb \
+ imx6sx-udoo-neo-basic.dtb \
+ imx6sx-udoo-neo-extended.dtb \
+ imx6sx-udoo-neo-full.dtb
dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ul-14x14-evk.dtb \
imx6ul-geam-kit.dtb \
+ imx6ul-liteboard.dtb \
imx6ul-pico-hobbit.dtb \
imx6ul-tx6ul-0010.dtb \
imx6ul-tx6ul-0011.dtb \
- imx6ul-tx6ul-mainboard.dtb
+ imx6ul-tx6ul-mainboard.dtb \
+ imx6ull-14x14-evk.dtb
dtb-$(CONFIG_SOC_IMX7D) += \
imx7d-cl-som-imx7.dtb \
imx7d-colibri-eval-v3.dtb \
@@ -561,6 +577,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
am335x-sl50.dtb \
am335x-wega-rdk.dtb
dtb-$(CONFIG_ARCH_OMAP4) += \
+ omap4-droid4-xt894.dtb \
omap4-duovero-parlor.dtb \
omap4-kc1.dtb \
omap4-panda.dtb \
@@ -588,15 +605,18 @@ dtb-$(CONFIG_SOC_DRA7XX) += \
am57xx-cl-som-am57x.dtb \
am57xx-sbc-am57x.dtb \
am572x-idk.dtb \
+ am571x-idk.dtb \
dra7-evm.dtb \
dra72-evm.dtb \
- dra72-evm-revc.dtb
+ dra72-evm-revc.dtb \
+ dra71-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += \
orion5x-kuroboxpro.dtb \
orion5x-lacie-d2-network.dtb \
orion5x-lacie-ethernet-disk-mini-v2.dtb \
orion5x-linkstation-lsgl.dtb \
orion5x-linkstation-lswtgl.dtb \
+ orion5x-lschl.dtb \
orion5x-lswsgl.dtb \
orion5x-maxtor-shared-storage-2.dtb \
orion5x-netgear-wnr854t.dtb \
@@ -604,7 +624,8 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
dtb-$(CONFIG_ARCH_PRIMA2) += \
prima2-evb.dtb
dtb-$(CONFIG_ARCH_OXNAS) += \
- wd-mbwe.dtb
+ wd-mbwe.dtb \
+ cloudengines-pogoplug-series-3.dtb
dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8060-dragonboard.dtb \
qcom-apq8064-arrow-sd-600eval.dtb \
@@ -620,7 +641,8 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8660-surf.dtb \
qcom-msm8960-cdp.dtb \
qcom-msm8974-lge-nexus5-hammerhead.dtb \
- qcom-msm8974-sony-xperia-honami.dtb
+ qcom-msm8974-sony-xperia-honami.dtb \
+ qcom-mdm9615-wp8548-mangoh-green.dtb
dtb-$(CONFIG_ARCH_REALVIEW) += \
arm-realview-pb1176.dtb \
arm-realview-pb11mp.dtb \
@@ -635,11 +657,14 @@ dtb-$(CONFIG_ARCH_REALVIEW) += \
arm-realview-pba8.dtb \
arm-realview-pbx-a9.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+ rk1108-evb.dtb \
rk3036-evb.dtb \
rk3036-kylin.dtb \
rk3066a-bqcurie2.dtb \
rk3066a-marsboard.dtb \
+ rk3066a-mk808.dtb \
rk3066a-rayeager.dtb \
+ rk3188-px3-evb.dtb \
rk3188-radxarock.dtb \
rk3228-evb.dtb \
rk3229-evb.dtb \
@@ -677,6 +702,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
r7s72100-rskrza1.dtb \
r8a73a4-ape6evm.dtb \
r8a7740-armadillo800eva.dtb \
+ r8a7743-sk-rzg1m.dtb \
+ r8a7745-sk-rzg1e.dtb \
r8a7778-bockw.dtb \
r8a7779-marzen.dtb \
r8a7790-lager.dtb \
@@ -690,12 +717,14 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
sh73a0-kzm9g.dtb
dtb-$(CONFIG_ARCH_SOCFPGA) += \
socfpga_arria5_socdk.dtb \
+ socfpga_arria10_socdk_qspi.dtb \
socfpga_arria10_socdk_sdmmc.dtb \
socfpga_cyclone5_mcvevk.dtb \
socfpga_cyclone5_socdk.dtb \
socfpga_cyclone5_de0_sockit.dtb \
socfpga_cyclone5_sockit.dtb \
socfpga_cyclone5_socrates.dtb \
+ socfpga_cyclone5_sodia.dtb \
socfpga_cyclone5_vining_fpga.dtb \
socfpga_vt.dtb
dtb-$(CONFIG_ARCH_SPEAR13XX) += \
@@ -712,16 +741,12 @@ dtb-$(CONFIG_ARCH_STI) += \
stih407-b2120.dtb \
stih410-b2120.dtb \
stih410-b2260.dtb \
- stih415-b2000.dtb \
- stih415-b2020.dtb \
- stih416-b2000.dtb \
- stih416-b2020.dtb \
- stih416-b2020e.dtb \
stih418-b2199.dtb
dtb-$(CONFIG_ARCH_STM32)+= \
stm32f429-disco.dtb \
stm32f469-disco.dtb \
- stm32429i-eval.dtb
+ stm32429i-eval.dtb \
+ stm32746g-eval.dtb
dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-a1000.dtb \
sun4i-a10-ba10-tvbox.dtb \
@@ -760,6 +785,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
sun5i-a13-olinuxino-micro.dtb \
sun5i-a13-q8-tablet.dtb \
sun5i-a13-utoo-p66.dtb \
+ sun5i-gr8-chip-pro.dtb \
sun5i-gr8-evb.dtb \
sun5i-r8-chip.dtb
dtb-$(CONFIG_MACH_SUN6I) += \
@@ -897,6 +923,7 @@ dtb-$(CONFIG_ARCH_VT8500) += \
wm8750-apc8750.dtb \
wm8850-w70v2.dtb
dtb-$(CONFIG_ARCH_ZYNQ) += \
+ zynq-microzed.dtb \
zynq-parallella.dtb \
zynq-zc702.dtb \
zynq-zc706.dtb \
@@ -920,6 +947,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
armada-385-db-ap.dtb \
armada-385-linksys-caiman.dtb \
armada-385-linksys-cobra.dtb \
+ armada-385-turris-omnia.dtb \
armada-388-clearfog.dtb \
armada-388-db.dtb \
armada-388-gp.dtb \
diff --git a/arch/arm/boot/dts/am335x-baltos-ir2110.dts b/arch/arm/boot/dts/am335x-baltos-ir2110.dts
index a9a97307d66c..501c7527121b 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir2110.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir2110.dts
@@ -54,16 +54,22 @@
dr_mode = "host";
};
+&davinci_mdio {
+ phy0: ethernet-phy@0 {
+ reg = <1>;
+ };
+};
+
&cpsw_emac0 {
- phy_id = <&davinci_mdio>, <1>;
phy-mode = "rmii";
dual_emac_res_vlan = <1>;
+ phy-handle = <&phy0>;
};
&cpsw_emac1 {
- phy_id = <&davinci_mdio>, <7>;
phy-mode = "rgmii-txid";
dual_emac_res_vlan = <2>;
+ phy-handle = <&phy1>;
};
&phy_sel {
diff --git a/arch/arm/boot/dts/am335x-baltos-ir3220.dts b/arch/arm/boot/dts/am335x-baltos-ir3220.dts
index fe002a17c04b..19f53b8569e1 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir3220.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir3220.dts
@@ -109,9 +109,9 @@
};
&cpsw_emac1 {
- phy_id = <&davinci_mdio>, <7>;
phy-mode = "rgmii-txid";
dual_emac_res_vlan = <2>;
+ phy-handle = <&phy1>;
};
&phy_sel {
diff --git a/arch/arm/boot/dts/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
index d0faa7b8c5da..2b9d7f4db23f 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir5221.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
@@ -114,7 +114,7 @@
&usb1 {
status = "okay";
- dr_mode = "otg";
+ dr_mode = "host";
};
&cpsw_emac0 {
@@ -127,9 +127,9 @@
};
&cpsw_emac1 {
- phy_id = <&davinci_mdio>, <7>;
phy-mode = "rgmii-txid";
dual_emac_res_vlan = <2>;
+ phy-handle = <&phy1>;
};
&phy_sel {
diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi
index dd45d172a892..efb5eae290a8 100644
--- a/arch/arm/boot/dts/am335x-baltos.dtsi
+++ b/arch/arm/boot/dts/am335x-baltos.dtsi
@@ -364,11 +364,14 @@
};
&davinci_mdio {
+ status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&davinci_mdio_default>;
pinctrl-1 = <&davinci_mdio_sleep>;
- status = "okay";
+ phy1: ethernet-phy@1 {
+ reg = <7>;
+ };
};
&mmc1 {
@@ -406,3 +409,7 @@
&gpio0 {
ti,no-reset-on-init;
};
+
+&gpio3 {
+ ti,no-reset-on-init;
+};
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 007b5e5a51a9..dc561d505bbe 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -6,6 +6,8 @@
* published by the Free Software Foundation.
*/
+#include <dt-bindings/mfd/tps65217.h>
+
/ {
cpus {
cpu@0 {
@@ -310,8 +312,23 @@
* by the hardware problems. (Tip: double-check by performing a current
* measurement after shutdown: it should be less than 1 mA.)
*/
+
+ interrupts = <7>; /* NMI */
+ interrupt-parent = <&intc>;
+
ti,pmic-shutdown-controller;
+ charger {
+ interrupts = <TPS65217_IRQ_AC>, <TPS65217_IRQ_USB>;
+ interrupts-names = "AC", "USB";
+ status = "okay";
+ };
+
+ pwrbutton {
+ interrupts = <TPS65217_IRQ_PB>;
+ status = "okay";
+ };
+
regulators {
dcdc1_reg: regulator@0 {
regulator-name = "vdds_dpr";
@@ -393,3 +410,8 @@
&sham {
status = "okay";
};
+
+&rtc {
+ clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
+ clock-names = "ext-clk", "int-clk";
+};
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
index 6bbb1fee0868..db00d8ef7b19 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -79,6 +79,14 @@
&lcdc {
status = "okay";
+
+ /* If you want to get 24 bit RGB and 16 BGR mode instead of
+ * current 16 bit RGB and 24 BGR modes, set the propety
+ * below to "crossed" and uncomment the video-ports -property
+ * in tda19988 node.
+ */
+ blue-and-red-wiring = "straight";
+
port {
lcdc_0: endpoint@0 {
remote-endpoint = <&hdmi_0>;
@@ -95,6 +103,9 @@
pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+ /* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+ /* video-ports = <0x234501>; */
+
#sound-dai-cells = <0>;
audio-ports = < TDA998x_I2S 0x03>;
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e82432c79f85..c2186ec2834b 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -783,3 +783,8 @@
pinctrl-names = "default";
pinctrl-0 = <&dcan1_pins_default>;
};
+
+&rtc {
+ clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
+ clock-names = "ext-clk", "int-clk";
+};
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index 975c36e332a2..e2548d1ce753 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -715,3 +715,8 @@
blue-and-red-wiring = "crossed";
};
+
+&rtc {
+ clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
+ clock-names = "ext-clk", "int-clk";
+};
diff --git a/arch/arm/boot/dts/am335x-icev2.dts b/arch/arm/boot/dts/am335x-icev2.dts
index 85e04c205542..1463df3b5b19 100644
--- a/arch/arm/boot/dts/am335x-icev2.dts
+++ b/arch/arm/boot/dts/am335x-icev2.dts
@@ -43,52 +43,52 @@
enable-active-high;
};
- leds0 {
+ leds-iio {
+ status = "disabled";
compatible = "gpio-leds";
-
- led0 {
+ led-out0 {
label = "out0";
gpios = <&tpic2810 0 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led1 {
+ led-out1 {
label = "out1";
gpios = <&tpic2810 1 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led2 {
+ led-out2 {
label = "out2";
gpios = <&tpic2810 2 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led3 {
+ led-out3 {
label = "out3";
gpios = <&tpic2810 3 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led4 {
+ led-out4 {
label = "out4";
gpios = <&tpic2810 4 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led5 {
+ led-out5 {
label = "out5";
gpios = <&tpic2810 5 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led6 {
+ led-out6 {
label = "out6";
gpios = <&tpic2810 6 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led7 {
+ led-out7 {
label = "out7";
gpios = <&tpic2810 7 GPIO_ACTIVE_HIGH>;
default-state = "off";
@@ -187,6 +187,8 @@
AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* (B17) spi0_d0.spi0_d0 */
AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* (B16) spi0_d1.spi0_d1 */
AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE0) /* (A16) spi0_cs0.spi0_cs0 */
+ AM33XX_IOPAD(0x960, PIN_INPUT_PULLUP | MUX_MODE0) /* (C15) spi0_cs1.spi0_cs1 */
+ AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7) /* (B12) mcasp0_aclkr.gpio3[18] */
>;
};
@@ -224,6 +226,31 @@
};
};
+&spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_default>;
+
+ sn65hvs882@1 {
+ compatible = "pisosr-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ load-gpios = <&gpio3 18 GPIO_ACTIVE_LOW>;
+
+ reg = <1>;
+ spi-max-frequency = <1000000>;
+ spi-cpol;
+ };
+};
+
+&tscadc {
+ status = "okay";
+ adc {
+ ti,adc-channels = <1 2 3 4 5 6 7>;
+ };
+};
+
#include "tps65910.dtsi"
&tps {
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 194d884c9de1..64c8aa9057a3 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -130,6 +130,7 @@
reg = <0x210000 0x2000>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
ranges = <0 0x210000 0x2000>;
am33xx_pinmux: pinmux@800 {
@@ -137,6 +138,7 @@
reg = <0x800 0x238>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x7f>;
};
@@ -505,6 +507,8 @@
interrupts = <75
76>;
ti,hwmods = "rtc";
+ clocks = <&clkdiv32k_ick>;
+ clock-names = "int-clk";
};
spi0: spi@48030000 {
@@ -855,6 +859,8 @@
interrupts = <16>;
ti,hwmods = "adc_tsc";
status = "disabled";
+ dmas = <&edma 53 0>, <&edma 57 0>;
+ dma-names = "fifo0", "fifo1";
tsc {
compatible = "ti,am3359-tsc";
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
index 0db19d39d24c..9fe545dbfa89 100644
--- a/arch/arm/boot/dts/am3517.dtsi
+++ b/arch/arm/boot/dts/am3517.dtsi
@@ -66,6 +66,7 @@
reg = <0x480025d8 0x24>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index a275fa956813..ac55f93fc91e 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -189,6 +189,7 @@
reg = <0x800 0x31c>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <32>;
@@ -871,6 +872,8 @@
clocks = <&adc_tsc_fck>;
clock-names = "fck";
status = "disabled";
+ dmas = <&edma 53 0>, <&edma 57 0>;
+ dma-names = "fifo0", "fifo1";
tsc {
compatible = "ti,am3359-tsc";
diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts
index 25ce611c6568..b76a7c0264a5 100644
--- a/arch/arm/boot/dts/am437x-idk-evm.dts
+++ b/arch/arm/boot/dts/am437x-idk-evm.dts
@@ -117,6 +117,58 @@
compatible = "fixed-clock";
clock-frequency = <32768>;
};
+
+ leds-iio {
+ status = "disabled";
+ compatible = "gpio-leds";
+ led-out0 {
+ label = "out0";
+ gpios = <&tpic2810 0 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out1 {
+ label = "out1";
+ gpios = <&tpic2810 1 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out2 {
+ label = "out2";
+ gpios = <&tpic2810 2 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out3 {
+ label = "out3";
+ gpios = <&tpic2810 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out4 {
+ label = "out4";
+ gpios = <&tpic2810 4 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out5 {
+ label = "out5";
+ gpios = <&tpic2810 5 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out6 {
+ label = "out6";
+ gpios = <&tpic2810 6 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out7 {
+ label = "out7";
+ gpios = <&tpic2810 7 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
};
&am43xx_pinmux {
@@ -178,6 +230,24 @@
>;
};
+ spi1_pins_default: spi1_pins_default {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x908, PIN_INPUT | MUX_MODE2) /* mii1_col.spi1_sclk */
+ AM4372_IOPAD(0x910, PIN_INPUT | MUX_MODE2) /* mii1_rx_er.spi1_d1 */
+ AM4372_IOPAD(0x944, PIN_OUTPUT | MUX_MODE2) /* rmii1_ref_clk.spi1_cs0 */
+ AM4372_IOPAD(0x90c, PIN_OUTPUT | MUX_MODE7) /* mii1_crs.gpio3_1 */
+ >;
+ };
+
+ spi1_pins_sleep: spi1_pins_sleep {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
ecap0_pins_default: backlight_pins_default {
pinctrl-single,pins = <
AM4372_IOPAD(0x964, PIN_OUTPUT | MUX_MODE0) /* ecap0_in_pwm0_out.ecap0_in_pwm0_out */
@@ -290,6 +360,33 @@
pinctrl-0 = <&i2c2_pins_default>;
pinctrl-1 = <&i2c2_pins_sleep>;
clock-frequency = <100000>;
+
+ tpic2810: tpic2810@60 {
+ compatible = "ti,tpic2810";
+ reg = <0x60>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&spi1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&spi1_pins_default>;
+ pinctrl-1 = <&spi1_pins_sleep>;
+ ti,pindir-d0-out-d1-in;
+
+ sn65hvs882: sn65hvs882@0 {
+ compatible = "pisosr-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ load-gpios = <&gpio3 1 GPIO_ACTIVE_LOW>;
+
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ spi-cpol;
+ };
};
&epwmss0 {
@@ -310,6 +407,10 @@
status = "okay";
};
+&gpio3 {
+ status = "okay";
+};
+
&gpio4 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts
new file mode 100644
index 000000000000..d6e43e5184c1
--- /dev/null
+++ b/arch/arm/boot/dts/am571x-idk.dts
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015-2016 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.
+ */
+/dts-v1/;
+
+#include "dra72x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "am57xx-idk-common.dtsi"
+
+/ {
+ model = "TI AM5718 IDK";
+ compatible = "ti,am5718-idk", "ti,am5718", "ti,dra7";
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x40000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ cpu0-led {
+ label = "status0:red:cpu0";
+ gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "cpu0";
+ };
+
+ usr0-led {
+ label = "status0:green:usr";
+ gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ heartbeat-led {
+ label = "status0:blue:heartbeat";
+ gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+
+ usr1-led {
+ label = "status1:red:usr";
+ gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ usr2-led {
+ label = "status1:green:usr";
+ gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ mmc0-led {
+ label = "status1:blue:mmc0";
+ gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&ldo1_reg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 27 0>; /* gpio 219 */
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts
index 87bbc66f0f21..27d9149cedba 100644
--- a/arch/arm/boot/dts/am572x-idk.dts
+++ b/arch/arm/boot/dts/am572x-idk.dts
@@ -83,3 +83,7 @@
bus-width = <4>;
cd-gpios = <&gpio6 27 0>; /* gpio 219 */
};
+
+&sn65hvs882 {
+ load-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
index 6df7829a2c15..78bee26361f1 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
@@ -204,6 +204,7 @@
interrupt-controller;
ti,system-power-controller;
+ ti,palmas-override-powerhold;
tps659038_pmic {
compatible = "ti,tps659038-pmic";
diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi
index 03cec62260e1..555ae21f2b9a 100644
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi
@@ -43,6 +43,58 @@
regulator-always-on;
regulator-boot-on;
};
+
+ leds-iio {
+ status = "disabled";
+ compatible = "gpio-leds";
+ led-out0 {
+ label = "out0";
+ gpios = <&tpic2810 0 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out1 {
+ label = "out1";
+ gpios = <&tpic2810 1 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out2 {
+ label = "out2";
+ gpios = <&tpic2810 2 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out3 {
+ label = "out3";
+ gpios = <&tpic2810 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out4 {
+ label = "out4";
+ gpios = <&tpic2810 4 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out5 {
+ label = "out5";
+ gpios = <&tpic2810 5 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out6 {
+ label = "out6";
+ gpios = <&tpic2810 6 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-out7 {
+ label = "out7";
+ gpios = <&tpic2810 7 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
};
&i2c1 {
@@ -57,6 +109,7 @@
#interrupt-cells = <2>;
interrupt-controller;
ti,system-power-controller;
+ ti,palmas-override-powerhold;
tps659038_pmic {
compatible = "ti,tps659038-pmic";
@@ -253,6 +306,28 @@
};
};
+&mcspi3 {
+ status = "okay";
+ ti,pindir-d0-out-d1-in;
+
+ sn65hvs882: sn65hvs882@0 {
+ compatible = "pisosr-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ spi-cpol;
+ };
+
+ tpic2810: tpic2810@60 {
+ compatible = "ti,tpic2810";
+ reg = <0x60>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
&uart3 {
status = "okay";
interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index 033fa63544f7..a9419f8e17e8 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -67,7 +67,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x40000000>; /* 1 GB */
};
@@ -86,18 +86,6 @@
status = "okay";
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
- };
-
ethernet@70000 {
pinctrl-0 = <&ge0_rgmii_pins>;
pinctrl-names = "default";
@@ -182,24 +170,6 @@
};
};
};
-
- pcie-controller {
- status = "okay";
- /*
- * The two PCIe units are accessible through
- * both standard PCIe slots and mini-PCIe
- * slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
};
sound {
@@ -261,6 +231,37 @@
};
};
+&pciec {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * both standard PCIe slots and mini-PCIe
+ * slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+
&spi0 {
pinctrl-0 = <&spi0_pins2>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
index e2a363b1dd8a..aeedc463daa6 100644
--- a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
+++ b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
@@ -62,7 +62,7 @@
stdout-path = &uart0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MiB */
};
@@ -72,20 +72,6 @@
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- pcie-controller {
- status = "okay";
-
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
sata@a0000 {
nr-ports = <2>;
@@ -262,6 +248,20 @@
};
};
+&pciec {
+ status = "okay";
+
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
&pinctrl {
sata_l_white_pin: sata-l-white-pin {
marvell,pins = "mpp57";
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index d5e19cd4d256..a1425409e570 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -54,7 +54,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -64,22 +64,6 @@
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Internal mini-PCIe connector */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* Connected on the PCB to a USB 3.0 XHCI controller */
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
@@ -113,17 +97,6 @@
};
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
- };
ethernet@70000 {
pinctrl-0 = <&ge0_rgmii_pins>;
pinctrl-names = "default";
@@ -197,6 +170,34 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected on the PCB to a USB 3.0 XHCI controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
&pinctrl {
pwr_led_pin: pwr-led-pin {
marvell,pins = "mpp63";
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index 39181b3fa90d..6bd9265f1062 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -56,7 +56,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -66,22 +66,6 @@
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Connected to Marvell 88SE9170 SATA controller */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* Connected to FL1009 USB 3.0 controller */
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
/* RTC is provided by Intersil ISL12057 I2C RTC chip */
@@ -99,14 +83,6 @@
status = "okay";
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- phy0: ethernet-phy@0 { /* Marvell 88E1318 */
- reg = <0>;
- };
- };
-
ethernet@74000 {
pinctrl-0 = <&ge1_rgmii_pins>;
pinctrl-names = "default";
@@ -120,8 +96,11 @@
};
i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
clock-frequency = <100000>;
+
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+
status = "okay";
isl12057: isl12057@68 {
@@ -257,6 +236,30 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* Connected to Marvell 88SE9170 SATA controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to FL1009 USB 3.0 controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+};
+
&pinctrl {
power_led_pin: power-led-pin {
marvell,pins = "mpp57";
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index 11565752b9f6..c84ab5bf1e18 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -56,7 +56,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -66,22 +66,6 @@
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Connected to FL1009 USB 3.0 controller */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* Connected to Marvell 88SE9215 SATA controller */
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
/* RTC is provided by Intersil ISL12057 I2C RTC chip */
@@ -93,18 +77,6 @@
status = "okay";
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- phy0: ethernet-phy@0 { /* Marvell 88E1318 */
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 { /* Marvell 88E1318 */
- reg = <1>;
- };
- };
-
ethernet@70000 {
pinctrl-0 = <&ge0_rgmii_pins>;
pinctrl-names = "default";
@@ -126,8 +98,11 @@
};
i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
clock-frequency = <100000>;
+
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+
status = "okay";
isl12057: isl12057@68 {
@@ -279,6 +254,34 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* Connected to FL1009 USB 3.0 controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to Marvell 88SE9215 SATA controller */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+};
+
&pinctrl {
poweroff: poweroff {
marvell,pins = "mpp60";
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index fbef730e8d37..c3fd6e49212f 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -67,7 +67,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -77,22 +77,6 @@
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Internal mini-PCIe connector */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* Internal mini-PCIe connector */
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
@@ -102,14 +86,6 @@
status = "okay";
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
- };
-
ethernet@70000 {
status = "okay";
phy = <&phy0>;
@@ -146,7 +122,7 @@
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
- button@1 {
+ button {
label = "Software Button";
linux,code = <KEY_POWER>;
gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
@@ -196,7 +172,7 @@
};
};
- dsa@0 {
+ dsa {
compatible = "marvell,dsa";
#address-cells = <2>;
#size-cells = <0>;
@@ -235,7 +211,32 @@
};
};
};
- };
+};
+
+&pciec {
+ status = "okay";
+
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Internal mini-PCIe connector */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
&pinctrl {
fan_pins: fan-pins {
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts b/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
index ae2e1fe50ef6..eb6af53b4954 100644
--- a/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
@@ -28,20 +28,7 @@
compatible = "seagate,dart-4", "marvell,armada370", "marvell,armada-370-xp";
soc {
- pcie-controller {
- /* SATA AHCI controller 88SE9170 */
- pcie@1,0 {
- status = "okay";
- };
- };
-
internal-regs {
- mdio {
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
- };
-
ethernet@74000 {
status = "okay";
pinctrl-0 = <&ge1_rgmii_pins>;
@@ -131,3 +118,17 @@
1300 0>;
};
};
+
+&pciec {
+ /* SATA AHCI controller 88SE9170 */
+ pcie@1,0 {
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi b/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
index 3036e25c5992..e9a5b952afc0 100644
--- a/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
@@ -23,7 +23,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -32,15 +32,6 @@
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
- pcie-controller {
- status = "okay";
-
- /* USB 3.0 bridge ASM1042A */
- pcie@2,0 {
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
@@ -51,15 +42,6 @@
status = "okay";
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
- };
-
ethernet@70000 {
status = "okay";
pinctrl-0 = <&ge0_rgmii_pins>;
@@ -159,19 +141,19 @@
#address-cells = <1>;
#size-cells = <0>;
- button@1 {
+ power {
label = "Power button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
debounce-interval = <100>;
};
- button@2 {
+ backup {
label = "Backup button";
linux,code = <KEY_OPTION>;
gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
debounce-interval = <100>;
};
- button@3 {
+ reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
@@ -208,6 +190,25 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* USB 3.0 bridge ASM1042A */
+ pcie@2,0 {
+ status = "okay";
+ };
+};
+
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
&pinctrl {
pinctrl-0 = <&hdd0_led_sata_pin>, <&hdd1_led_sata_pin>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
index 01cded310cbc..d079a89ee5a2 100644
--- a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
@@ -24,7 +24,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -33,15 +33,6 @@
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
- pcie-controller {
- status = "okay";
-
- /* USB 3.0 Bridge ASM1042A */
- pcie@1,0 {
- status = "okay";
- };
- };
-
internal-regs {
coherency-fabric@20200 {
broken-idle;
@@ -51,15 +42,6 @@
status = "okay";
};
- mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
- };
-
ethernet@74000 {
status = "okay";
pinctrl-0 = <&ge1_rgmii_pins>;
@@ -107,19 +89,19 @@
#address-cells = <1>;
#size-cells = <0>;
- button@1 {
+ power {
label = "Power button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
debounce-interval = <100>;
};
- button@2 {
+ reset {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
debounce-interval = <100>;
};
- button@3 {
+ button {
label = "USB VBUS error";
linux,code = <KEY_UNKNOWN>;
gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
@@ -143,6 +125,24 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* USB 3.0 Bridge ASM1042A */
+ pcie@1,0 {
+ status = "okay";
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
&pinctrl {
pinctrl-0 = <&sata_led_pin>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
index a9cc42776874..99f9de229ea8 100644
--- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts
+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
@@ -70,7 +70,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
@@ -127,12 +127,6 @@
status = "okay";
};
- mdio {
- phy1: ethernet-phy@1 { /* Marvell 88E1512 */
- reg = <1>;
- };
- };
-
ethernet@70000 {
status = "okay";
phy = <&phy1>;
@@ -192,7 +186,7 @@
pinctrl-0 = <&sata1_pwr_pin &sata2_pwr_pin>;
pinctrl-names = "default";
- sata1_regulator: sata1-regulator {
+ sata1_regulator: sata1-regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
regulator-name = "SATA1 Power";
@@ -205,7 +199,7 @@
gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
};
- sata2_regulator: sata2-regulator {
+ sata2_regulator: sata2-regulator@2 {
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "SATA2 Power";
@@ -220,6 +214,12 @@
};
};
+&mdio {
+ phy1: ethernet-phy@1 { /* Marvell 88E1512 */
+ reg = <1>;
+ };
+};
+
&pinctrl {
disk1_led_pin: disk1-led-pin {
marvell,pins = "mpp31";
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 3ccedc9dffb2..b0520bdeea27 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -50,8 +50,6 @@
* 370 and Armada XP SoC.
*/
-/include/ "skeleton64.dtsi"
-
#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
/ {
@@ -86,7 +84,7 @@
pcie-mem-aperture = <0xf8000000 0x7e00000>;
pcie-io-aperture = <0xffe00000 0x100000>;
- devbus-bootcs {
+ devbus_bootcs: devbus-bootcs {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
@@ -96,7 +94,7 @@
status = "disabled";
};
- devbus-cs0 {
+ devbus_cs0: devbus-cs0 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
@@ -106,7 +104,7 @@
status = "disabled";
};
- devbus-cs1 {
+ devbus_cs1: devbus-cs1 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
@@ -116,7 +114,7 @@
status = "disabled";
};
- devbus-cs2 {
+ devbus_cs2: devbus-cs2 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
@@ -126,7 +124,7 @@
status = "disabled";
};
- devbus-cs3 {
+ devbus_cs3: devbus-cs3 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
@@ -142,7 +140,7 @@
#size-cells = <1>;
ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
- rtc@10300 {
+ rtc: rtc@10300 {
compatible = "marvell,orion-rtc";
reg = <0x10300 0x20>;
interrupts = <50>;
@@ -214,33 +212,38 @@
msi-controller;
};
- coherency-fabric@20200 {
+ coherencyfab: coherency-fabric@20200 {
compatible = "marvell,coherency-fabric";
reg = <0x20200 0xb0>, <0x21010 0x1c>;
};
- timer@20300 {
+ timer: timer@20300 {
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
};
- watchdog@20300 {
+ watchdog: watchdog@20300 {
reg = <0x20300 0x34>, <0x20704 0x4>;
};
- pmsu@22000 {
+ cpurst: cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x8>;
+ };
+
+ pmsu: pmsu@22000 {
compatible = "marvell,armada-370-pmsu";
reg = <0x22000 0x1000>;
};
- usb@50000 {
+ usb0: usb@50000 {
compatible = "marvell,orion-ehci";
reg = <0x50000 0x500>;
interrupts = <45>;
status = "disabled";
};
- usb@51000 {
+ usb1: usb@51000 {
compatible = "marvell,orion-ehci";
reg = <0x51000 0x500>;
interrupts = <46>;
@@ -254,7 +257,7 @@
status = "disabled";
};
- mdio: mdio {
+ mdio: mdio@72004 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
@@ -269,7 +272,7 @@
status = "disabled";
};
- sata@a0000 {
+ sata: sata@a0000 {
compatible = "marvell,armada-370-sata";
reg = <0xa0000 0x5000>;
interrupts = <55>;
@@ -278,7 +281,7 @@
status = "disabled";
};
- nand@d0000 {
+ nand: nand@d0000 {
compatible = "marvell,armada370-nand";
reg = <0xd0000 0x54>;
#address-cells = <1>;
@@ -288,7 +291,7 @@
status = "disabled";
};
- mvsdio@d4000 {
+ sdio: mvsdio@d4000 {
compatible = "marvell,orion-sdio";
reg = <0xd4000 0x200>;
interrupts = <54>;
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index b4258105e91f..b704bcc597f7 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -50,9 +50,11 @@
*/
#include "armada-370-xp.dtsi"
-/include/ "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
model = "Marvell Armada 370 family SoC";
compatible = "marvell,armada370", "marvell,armada-370-xp";
@@ -70,7 +72,7 @@
reg = <MBUS_ID(0x01, 0xe0) 0 0x100000>;
};
- pcie-controller {
+ pciec: pcie-controller@82000000 {
compatible = "marvell,armada-370-pcie";
status = "disabled";
device_type = "pci";
@@ -89,7 +91,7 @@
0x82000000 0x2 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
0x81000000 0x2 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>;
- pcie@1,0 {
+ pcie0: pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
@@ -106,7 +108,7 @@
status = "disabled";
};
- pcie@2,0 {
+ pcie2: pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
@@ -125,7 +127,7 @@
};
internal-regs {
- L2: l2-cache {
+ L2: l2-cache@8000 {
compatible = "marvell,aurora-outer-cache";
reg = <0x08000 0x1000>;
cache-id-part = <0x100>;
@@ -134,14 +136,6 @@
wt-override;
};
- i2c0: i2c@11000 {
- reg = <0x11000 0x20>;
- };
-
- i2c1: i2c@11100 {
- reg = <0x11100 0x20>;
- };
-
gpio0: gpio@18100 {
compatible = "marvell,orion-gpio";
reg = <0x18100 0x40>;
@@ -175,22 +169,8 @@
interrupts = <91>;
};
- /*
- * Default UART pinctrl setting without RTS/CTS, can
- * be overwritten on board level if a different
- * configuration is used.
- */
- uart0: serial@12000 {
- pinctrl-0 = <&uart0_pins>;
- pinctrl-names = "default";
- };
-
- uart1: serial@12100 {
- pinctrl-0 = <&uart1_pins>;
- pinctrl-names = "default";
- };
- system-controller@18200 {
+ systemc: system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0x18200 0x100>;
};
@@ -208,37 +188,18 @@
#clock-cells = <1>;
};
- thermal@18300 {
+ thermal: thermal@18300 {
compatible = "marvell,armada370-thermal";
reg = <0x18300 0x4
0x18304 0x4>;
status = "okay";
};
- sscg@18330 {
+ sscg: sscg@18330 {
reg = <0x18330 0x4>;
};
- interrupt-controller@20a00 {
- reg = <0x20a00 0x1d0>, <0x21870 0x58>;
- };
-
- timer@20300 {
- compatible = "marvell,armada-370-timer";
- clocks = <&coreclk 2>;
- };
-
- watchdog@20300 {
- compatible = "marvell,armada-370-wdt";
- clocks = <&coreclk 2>;
- };
-
- cpurst@20800 {
- compatible = "marvell,armada-370-cpu-reset";
- reg = <0x20800 0x8>;
- };
-
- cpu-config@21000 {
+ cpuconf: cpu-config@21000 {
compatible = "marvell,armada-370-cpu-config";
reg = <0x21000 0x8>;
};
@@ -253,15 +214,7 @@
status = "disabled";
};
- usb@50000 {
- clocks = <&coreclk 0>;
- };
-
- usb@51000 {
- clocks = <&coreclk 0>;
- };
-
- xor@60800 {
+ xor0: xor@60800 {
compatible = "marvell,orion-xor";
reg = <0x60800 0x100
0x60A00 0x100>;
@@ -280,7 +233,7 @@
};
};
- xor@60900 {
+ xor1: xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
0x60b00 0x100>;
@@ -299,15 +252,7 @@
};
};
- ethernet@70000 {
- compatible = "marvell,armada-370-neta";
- };
-
- ethernet@74000 {
- compatible = "marvell,armada-370-neta";
- };
-
- crypto@90000 {
+ cesa: crypto@90000 {
compatible = "marvell,armada-370-crypto";
reg = <0x90000 0x10000>;
reg-names = "regs";
@@ -342,6 +287,59 @@
};
};
+/*
+ * Default UART pinctrl setting without RTS/CTS, can be overwritten on
+ * board level if a different configuration is used.
+ */
+
+&uart0 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+};
+
+&uart1 {
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+};
+
+&i2c0 {
+ reg = <0x11000 0x20>;
+};
+
+&i2c1 {
+ reg = <0x11100 0x20>;
+};
+
+&mpic {
+ reg = <0x20a00 0x1d0>, <0x21870 0x58>;
+};
+
+&timer {
+ compatible = "marvell,armada-370-timer";
+ clocks = <&coreclk 2>;
+};
+
+&watchdog {
+ compatible = "marvell,armada-370-wdt";
+ clocks = <&coreclk 2>;
+};
+
+&usb0 {
+ clocks = <&coreclk 0>;
+};
+
+&usb1 {
+ clocks = <&coreclk 0>;
+};
+
+&eth0 {
+ compatible = "marvell,armada-370-neta";
+};
+
+&eth1 {
+ compatible = "marvell,armada-370-neta";
+};
+
&pinctrl {
compatible = "marvell,mv88f6710-pinctrl";
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
index cded5f0a262d..ef45cbeb3e7d 100644
--- a/arch/arm/boot/dts/armada-375-db.dts
+++ b/arch/arm/boot/dts/armada-375-db.dts
@@ -58,7 +58,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x40000000>; /* 1 GB */
};
@@ -69,138 +69,141 @@
MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
- internal-regs {
- spi@10600 {
- pinctrl-0 = <&spi0_pins>;
- pinctrl-names = "default";
- /*
- * SPI conflicts with NAND, so we disable it
- * here, and select NAND as the enabled device
- * by default.
- */
- status = "disabled";
-
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "n25q128a13", "jedec,spi-nor";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <108000000>;
- };
- };
-
- i2c@11000 {
- status = "okay";
- clock-frequency = <100000>;
- pinctrl-0 = <&i2c0_pins>;
- pinctrl-names = "default";
- };
-
- i2c@11100 {
- status = "okay";
- clock-frequency = <100000>;
- pinctrl-0 = <&i2c1_pins>;
- pinctrl-names = "default";
- };
-
- serial@12000 {
- status = "okay";
- };
-
- pinctrl {
- sdio_st_pins: sdio-st-pins {
- marvell,pins = "mpp44", "mpp45";
- marvell,function = "gpio";
- };
- };
-
- sata@a0000 {
- status = "okay";
- nr-ports = <2>;
- };
-
- nand: nand@d0000 {
- pinctrl-0 = <&nand_pins>;
- pinctrl-names = "default";
- status = "okay";
- num-cs = <1>;
- marvell,nand-keep-config;
- marvell,nand-enable-arbiter;
- nand-on-flash-bbt;
- nand-ecc-strength = <4>;
- nand-ecc-step-size = <512>;
-
- partition@0 {
- label = "U-Boot";
- reg = <0 0x800000>;
- };
- partition@800000 {
- label = "Linux";
- reg = <0x800000 0x800000>;
- };
- partition@1000000 {
- label = "Filesystem";
- reg = <0x1000000 0x3f000000>;
- };
- };
-
- usb@54000 {
- status = "okay";
- };
-
- usb3@58000 {
- status = "okay";
- };
-
- mvsdio@d4000 {
- pinctrl-0 = <&sdio_pins &sdio_st_pins>;
- pinctrl-names = "default";
- status = "okay";
- cd-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
- wp-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
- };
-
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy3: ethernet-phy@3 {
- reg = <3>;
- };
- };
-
- ethernet@f0000 {
- status = "okay";
-
- eth0@c4000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
-
- eth1@c5000 {
- status = "okay";
- phy = <&phy3>;
- phy-mode = "gmii";
- };
- };
- };
-
- pcie-controller {
- status = "okay";
- /*
- * The two PCIe units are accessible through
- * standard PCIe slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
};
};
+&pciec {
+ status = "okay";
+};
+
+/*
+ * The two PCIe units are accessible through
+ * standard PCIe slots on the board.
+ */
+&pcie0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+};
+
+&pcie1 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+};
+
+
+&spi0 {
+ pinctrl-0 = <&spi0_pins>;
+ pinctrl-names = "default";
+
+ /*
+ * SPI conflicts with NAND, so we disable it here, and
+ * select NAND as the enabled device by default.
+ */
+
+ status = "disabled";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&pinctrl {
+ sdio_st_pins: sdio-st-pins {
+ marvell,pins = "mpp44", "mpp45";
+ marvell,function = "gpio";
+ };
+};
+
+&sata {
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&nand {
+ pinctrl-0 = <&nand_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x800000>;
+ };
+ partition@800000 {
+ label = "Linux";
+ reg = <0x800000 0x800000>;
+ };
+ partition@1000000 {
+ label = "Filesystem";
+ reg = <0x1000000 0x3f000000>;
+ };
+};
+
+&usb1 {
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
+
+&sdio {
+ pinctrl-0 = <&sdio_pins &sdio_st_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ cd-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+};
+
+&mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+};
+
+&ethernet {
+ status = "okay";
+};
+
+
+&eth0 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+};
+
+&eth1 {
+ status = "okay";
+ phy = <&phy3>;
+ phy-mode = "gmii";
+};
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
index cc952cf8ec30..f515591e8733 100644
--- a/arch/arm/boot/dts/armada-375.dtsi
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -45,7 +45,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "skeleton.dtsi"
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/phy/phy.h>
@@ -53,6 +52,9 @@
#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
model = "Marvell Armada 375 family SoC";
compatible = "marvell,armada375";
@@ -65,7 +67,7 @@
};
clocks {
- /* 2 GHz fixed main PLL */
+ /* 1 GHz fixed main PLL */
mainpll: mainpll {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -84,12 +86,12 @@
#size-cells = <0>;
enable-method = "marvell,armada-375-smp";
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
};
- cpu@1 {
+ cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
@@ -115,7 +117,7 @@
reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
};
- devbus-bootcs {
+ devbus_bootcs: devbus-bootcs {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
@@ -125,7 +127,7 @@
status = "disabled";
};
- devbus-cs0 {
+ devbus_cs0: devbus-cs0 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
@@ -135,7 +137,7 @@
status = "disabled";
};
- devbus-cs1 {
+ devbus_cs1: devbus-cs1 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
@@ -145,7 +147,7 @@
status = "disabled";
};
- devbus-cs2 {
+ devbus_cs2: devbus-cs2 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
@@ -155,7 +157,7 @@
status = "disabled";
};
- devbus-cs3 {
+ devbus_cs3: devbus-cs3 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
@@ -182,12 +184,12 @@
prefetch-data = <1>;
};
- scu@c000 {
+ scu: scu@c000 {
compatible = "arm,cortex-a9-scu";
reg = <0xc000 0x58>;
};
- timer@c600 {
+ timer0: timer@c600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xc600 0x20>;
interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
@@ -203,7 +205,7 @@
<0xc100 0x100>;
};
- mdio {
+ mdio: mdio@c0054 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
@@ -212,7 +214,7 @@
};
/* Network controller */
- ethernet@f0000 {
+ ethernet: ethernet@f0000 {
compatible = "marvell,armada-375-pp2";
reg = <0xf0000 0xa000>, /* Packet Processor regs */
<0xc0000 0x3060>, /* LMS regs */
@@ -222,20 +224,20 @@
clock-names = "pp_clk", "gop_clk";
status = "disabled";
- eth0: eth0@c4000 {
+ eth0: eth0 {
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
port-id = <0>;
status = "disabled";
};
- eth1: eth1@c5000 {
+ eth1: eth1 {
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
port-id = <1>;
status = "disabled";
};
};
- rtc@10300 {
+ rtc: rtc@10300 {
compatible = "marvell,orion-rtc";
reg = <0x10300 0x20>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
@@ -307,7 +309,7 @@
status = "disabled";
};
- pinctrl {
+ pinctrl: pinctrl@18000 {
compatible = "marvell,mv88f6720-pinctrl";
reg = <0x18000 0x24>;
@@ -382,7 +384,7 @@
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
};
- system-controller@18200 {
+ systemc: system-controller@18200 {
compatible = "marvell,armada-375-system-controller";
reg = <0x18200 0x100>;
};
@@ -415,7 +417,7 @@
interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
};
- timer@20300 {
+ timer1: timer@20300 {
compatible = "marvell,armada-375-timer", "marvell,armada-370-timer";
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
@@ -428,24 +430,24 @@
clock-names = "nbclk", "fixed";
};
- watchdog@20300 {
+ watchdog: watchdog@20300 {
compatible = "marvell,armada-375-wdt";
reg = <0x20300 0x34>, <0x20704 0x4>, <0x18254 0x4>;
clocks = <&coreclk 0>, <&refclk>;
clock-names = "nbclk", "fixed";
};
- cpurst@20800 {
+ cpurst: cpurst@20800 {
compatible = "marvell,armada-370-cpu-reset";
reg = <0x20800 0x10>;
};
- coherency-fabric@21010 {
+ coherencyfab: coherency-fabric@21010 {
compatible = "marvell,armada-375-coherency-fabric";
reg = <0x21010 0x1c>;
};
- usb@50000 {
+ usb0: usb@50000 {
compatible = "marvell,orion-ehci";
reg = <0x50000 0x500>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
@@ -455,7 +457,7 @@
status = "disabled";
};
- usb@54000 {
+ usb1: usb@54000 {
compatible = "marvell,orion-ehci";
reg = <0x54000 0x500>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
@@ -463,7 +465,7 @@
status = "disabled";
};
- usb3@58000 {
+ usb2: usb3@58000 {
compatible = "marvell,armada-375-xhci";
reg = <0x58000 0x20000>,<0x5b880 0x80>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
@@ -473,7 +475,7 @@
status = "disabled";
};
- xor@60800 {
+ xor0: xor@60800 {
compatible = "marvell,orion-xor";
reg = <0x60800 0x100
0x60A00 0x100>;
@@ -493,7 +495,7 @@
};
};
- xor@60900 {
+ xor1: xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
0x60b00 0x100>;
@@ -513,7 +515,7 @@
};
};
- crypto@90000 {
+ cesa: crypto@90000 {
compatible = "marvell,armada-375-crypto";
reg = <0x90000 0x10000>;
reg-names = "regs";
@@ -528,7 +530,7 @@
marvell,crypto-sram-size = <0x800>;
};
- sata@a0000 {
+ sata: sata@a0000 {
compatible = "marvell,armada-370-sata";
reg = <0xa0000 0x5000>;
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
@@ -537,7 +539,7 @@
status = "disabled";
};
- nand@d0000 {
+ nand: nand@d0000 {
compatible = "marvell,armada370-nand";
reg = <0xd0000 0x54>;
#address-cells = <1>;
@@ -547,7 +549,7 @@
status = "disabled";
};
- mvsdio@d4000 {
+ sdio: mvsdio@d4000 {
compatible = "marvell,orion-sdio";
reg = <0xd4000 0x200>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
@@ -559,7 +561,7 @@
status = "disabled";
};
- thermal@e8078 {
+ thermal: thermal@e8078 {
compatible = "marvell,armada375-thermal";
reg = <0xe8078 0x4>, <0xe807c 0x8>;
status = "okay";
@@ -580,7 +582,7 @@
};
};
- pcie-controller {
+ pciec: pcie-controller@82000000 {
compatible = "marvell,armada-370-pcie";
status = "disabled";
device_type = "pci";
@@ -599,7 +601,7 @@
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1 MEM */
0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1 IO */>;
- pcie@1,0 {
+ pcie0: pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
@@ -616,7 +618,7 @@
status = "disabled";
};
- pcie@2,0 {
+ pcie1: pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
new file mode 100644
index 000000000000..ab49acb2d452
--- /dev/null
+++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -0,0 +1,340 @@
+/*
+ * Device Tree file for the Turris Omnia
+ *
+ * Copyright (C) 2016 Uwe Kleine-König <uwe@kleine-koenig.org>
+ * Copyright (C) 2016 Tomas Hlavacek <tmshlvkc@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 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.
+ *
+ * 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.
+ */
+
+/*
+ * Schematic available at https://www.turris.cz/doc/_media/rtrom01-schema.pdf
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-385.dtsi"
+
+/ {
+ model = "Turris Omnia";
+ compatible = "cznic,turris-omnia", "marvell,armada385", "marvell,armada380";
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1024 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 {
+
+ /* USB part of the PCIe2/USB 2.0 port */
+ usb@58000 {
+ status = "okay";
+ };
+
+ sata@a8000 {
+ status = "okay";
+ };
+
+ sdhci@d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ status = "okay";
+
+ bus-width = <8>;
+ no-1-8-v;
+ non-removable;
+ };
+
+ usb3@f0000 {
+ status = "okay";
+ };
+
+ usb3@f8000 {
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@3,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
+
+/* Connected to 88E6176 switch, port 6 */
+&eth0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ status = "okay";
+ phy-mode = "rgmii-id";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+/* Connected to 88E6176 switch, port 5 */
+&eth1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ status = "okay";
+ phy-mode = "rgmii-id";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+/* WAN port */
+&eth2 {
+ status = "okay";
+ phy-mode = "sgmii";
+ phy = <&phy1>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ i2cmux@70 {
+ compatible = "nxp,pca9547";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ status = "okay";
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ /* STM32F0 command interface at address 0x2a */
+ /* leds device (in STM32F0) at address 0x2b */
+
+ eeprom@54 {
+ compatible = "at,24c64";
+ reg = <0x54>;
+
+ /* The EEPROM contains data for bootloader.
+ * Contents:
+ * struct omnia_eeprom {
+ * u32 magic; (=0x0341a034 in LE)
+ * u32 ramsize; (in GiB)
+ * char regdomain[4];
+ * u32 crc32;
+ * };
+ */
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ /* routed to PCIe0/mSATA connector (CN7A) */
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ /* routed to PCIe1/USB2 connector (CN61A) */
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ /* routed to PCIe2 connector (CN62A) */
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ /* routed to SFP+ */
+ };
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ /* ATSHA204A at address 0x64 */
+ };
+
+ i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ /* exposed on pin header */
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ pcawan: gpio@71 {
+ /*
+ * GPIO expander for SFP+ signals and
+ * and phy irq
+ */
+ compatible = "nxp,pca9538";
+ reg = <0x71>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcawan_pins>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+ };
+};
+
+&mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ status = "okay";
+
+ phy1: phy@1 {
+ status = "okay";
+ compatible = "ethernet-phy-id0141.0DD1", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+
+ /* irq is connected to &pcawan pin 7 */
+ };
+
+ /* Switch MV88E7176 at address 0x10 */
+};
+
+&pinctrl {
+ pcawan_pins: pcawan-pins {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
+ };
+
+ spi0cs0_pins: spi0cs0-pins {
+ marvell,pins = "mpp25";
+ marvell,function = "spi0";
+ };
+
+ spi0cs1_pins: spi0cs1-pins {
+ marvell,pins = "mpp26";
+ marvell,function = "spi0";
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins &spi0cs0_pins>;
+ status = "okay";
+
+ spi-nor@0 {
+ compatible = "spansion,s25fl164k", "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x0 0x00100000>;
+ label = "U-Boot";
+ };
+
+ partition@100000 {
+ reg = <0x00100000 0x00700000>;
+ label = "Rescue system";
+ };
+ };
+ };
+
+ /* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */
+};
+
+&uart0 {
+ /* Pin header CN10 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ /* Pin header CN11 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index 2d7668848c5a..7450e9fea45d 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -661,7 +661,7 @@
};
clocks {
- /* 2 GHz fixed main PLL */
+ /* 1 GHz fixed main PLL */
mainpll: mainpll {
compatible = "fixed-clock";
#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
index 34cba87f9200..de171baffcf6 100644
--- a/arch/arm/boot/dts/armada-39x.dtsi
+++ b/arch/arm/boot/dts/armada-39x.dtsi
@@ -573,7 +573,7 @@
};
clocks {
- /* 2 GHz fixed main PLL */
+ /* 1 GHz fixed main PLL */
mainpll: mainpll {
compatible = "fixed-clock";
#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
index ce152719bc28..1e1fc4fccbad 100644
--- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts
+++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -62,7 +62,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000 0x40000000>; /* 1GB */
};
@@ -73,28 +73,6 @@
MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* First mini-PCIe port */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* Second mini-PCIe port */
- pcie@2,0 {
- /* Port 0, Lane 1 */
- status = "okay";
- };
-
- /* Renesas uPD720202 USB 3.0 controller */
- pcie@3,0 {
- /* Port 0, Lane 3 */
- status = "okay";
- };
- };
-
internal-regs {
/* UART0 */
serial@12000 {
@@ -111,16 +89,6 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
- };
-
ethernet@70000 {
pinctrl-0 = <&ge0_rgmii_pins>;
pinctrl-names = "default";
@@ -145,7 +113,7 @@
pinctrl-0 = <&keys_pin>;
pinctrl-names = "default";
- button@1 {
+ reset {
label = "Factory Reset Button";
linux,code = <KEY_SETUP>;
gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
@@ -153,6 +121,38 @@
};
};
+&mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&pciec {
+ status = "okay";
+
+ /* First mini-PCIe port */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Second mini-PCIe port */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Renesas uPD720202 USB 3.0 controller */
+ pcie@3,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+};
+
&pinctrl {
pinctrl-0 = <&phy_int_pin>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index 075120bc3ec4..44a724d39dbe 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -67,7 +67,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x00000000 0 0x80000000>; /* 2 GB */
};
@@ -108,39 +108,6 @@
};
};
- pcie-controller {
- status = "okay";
-
- /*
- * All 6 slots are physically present as
- * standard PCIe slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@2,0 {
- /* Port 0, Lane 1 */
- status = "okay";
- };
- pcie@3,0 {
- /* Port 0, Lane 2 */
- status = "okay";
- };
- pcie@4,0 {
- /* Port 0, Lane 3 */
- status = "okay";
- };
- pcie@9,0 {
- /* Port 2, Lane 0 */
- status = "okay";
- };
- pcie@10,0 {
- /* Port 3, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
@@ -160,24 +127,6 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
-
- phy2: ethernet-phy@2 {
- reg = <25>;
- };
-
- phy3: ethernet-phy@3 {
- reg = <27>;
- };
- };
-
ethernet@70000 {
status = "okay";
phy = <&phy0>;
@@ -266,6 +215,57 @@
};
};
+&pciec {
+ status = "okay";
+
+ /*
+ * All 6 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+ pcie@3,0 {
+ /* Port 0, Lane 2 */
+ status = "okay";
+ };
+ pcie@4,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@10,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <25>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <27>;
+ };
+};
+
&spi0 {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index 190e4eccb180..72cb8fa377e3 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -68,7 +68,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
/*
* 8 GB of plug-in RAM modules by default.The amount
@@ -127,27 +127,6 @@
};
};
- pcie-controller {
- status = "okay";
-
- /*
- * The 3 slots are physically present as
- * standard PCIe slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@9,0 {
- /* Port 2, Lane 0 */
- status = "okay";
- };
- pcie@10,0 {
- /* Port 3, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
@@ -175,24 +154,6 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 {
- reg = <16>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <17>;
- };
-
- phy2: ethernet-phy@2 {
- reg = <18>;
- };
-
- phy3: ethernet-phy@3 {
- reg = <19>;
- };
- };
-
ethernet@70000 {
status = "okay";
phy = <&phy0>;
@@ -251,6 +212,45 @@
};
};
+&pciec {
+ status = "okay";
+
+ /*
+ * The 3 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@10,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@0 {
+ reg = <16>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <17>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <18>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <19>;
+ };
+};
+
&spi0 {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
index 8af463f26ea1..d848ae9007db 100644
--- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
+++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -57,7 +57,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x00000000 0 0x20000000>; /* 512MB */
};
@@ -68,37 +68,11 @@
MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Quad port sata: Marvell 88SX7042 */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* USB 3.0 xHCI controller: NEC D720200F1 */
- pcie@5,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 { /* Marvell 88E1318 */
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 { /* Marvell 88E1318 */
- reg = <1>;
- };
- };
-
ethernet@70000 {
pinctrl-0 = <&ge0_rgmii_pins>;
pinctrl-names = "default";
@@ -295,6 +269,31 @@
gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
};
};
+&pciec {
+ status = "okay";
+
+ /* Quad port sata: Marvell 88SX7042 */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* USB 3.0 xHCI controller: NEC D720200F1 */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+};
&pinctrl {
poweroff_pin: poweroff-pin {
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index 076f27f22c3b..83ac884c0f8a 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -62,7 +62,7 @@
stdout-path = &uart0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000 0x10000000>; /* 256MB */
};
@@ -73,28 +73,6 @@
MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Etron EJ168 USB 3.0 controller */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* First mini-PCIe port */
- pcie@2,0 {
- /* Port 0, Lane 1 */
- status = "okay";
- };
-
- /* Second mini-PCIe port */
- pcie@3,0 {
- /* Port 0, Lane 3 */
- status = "okay";
- };
- };
-
internal-regs {
rtc@10300 {
@@ -289,13 +267,13 @@
pinctrl-0 = <&keys_pin>;
pinctrl-names = "default";
- button@1 {
+ wps {
label = "WPS";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
};
- button@2 {
+ reset {
label = "Factory Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
@@ -323,7 +301,7 @@
4500 1>;
};
- dsa@0 {
+ dsa {
compatible = "marvell,dsa";
#address-cells = <2>;
#size-cells = <0>;
@@ -369,6 +347,28 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* Etron EJ168 USB 3.0 controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* First mini-PCIe port */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Second mini-PCIe port */
+ pcie@3,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
+ };
+};
+
&pinctrl {
keys_pin: keys-pin {
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
index 6522b04f4a8e..16277380e714 100644
--- a/arch/arm/boot/dts/armada-xp-matrix.dts
+++ b/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -55,7 +55,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
/*
* This board has 4 GB of RAM, but the last 256 MB of
@@ -99,18 +99,18 @@
};
};
- pcie-controller {
- status = "okay";
-
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- };
-
usb@50000 {
status = "okay";
};
};
};
};
+
+&pciec {
+ status = "okay";
+
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index 6e6d0f04bf2b..05c164b5786d 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -86,7 +86,7 @@
* configured as x4 or quad x1 lanes. One unit is
* x1 only.
*/
- pcie-controller {
+ pciec: pcie-controller@82000000 {
compatible = "marvell,armada-xp-pcie";
status = "disabled";
device_type = "pci";
@@ -114,7 +114,7 @@
0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>;
- pcie@1,0 {
+ pcie1: pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
@@ -131,7 +131,7 @@
status = "disabled";
};
- pcie@2,0 {
+ pcie2: pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
@@ -148,7 +148,7 @@
status = "disabled";
};
- pcie@3,0 {
+ pcie3: pcie@3,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
@@ -165,7 +165,7 @@
status = "disabled";
};
- pcie@4,0 {
+ pcie4: pcie@4,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
@@ -182,7 +182,7 @@
status = "disabled";
};
- pcie@5,0 {
+ pcie5: pcie@5,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
reg = <0x2800 0 0 0 0>;
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index c5fdc99f0dbe..07894b0d3e59 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -87,7 +87,7 @@
* configured as x4 or quad x1 lanes. One unit is
* x4 only.
*/
- pcie-controller {
+ pciec: pcie-controller@82000000 {
compatible = "marvell,armada-xp-pcie";
status = "disabled";
device_type = "pci";
@@ -129,7 +129,7 @@
0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>;
- pcie@1,0 {
+ pcie1: pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
@@ -146,7 +146,7 @@
status = "disabled";
};
- pcie@2,0 {
+ pcie2: pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
@@ -163,7 +163,7 @@
status = "disabled";
};
- pcie@3,0 {
+ pcie3: pcie@3,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
@@ -180,7 +180,7 @@
status = "disabled";
};
- pcie@4,0 {
+ pcie4: pcie@4,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
@@ -197,7 +197,7 @@
status = "disabled";
};
- pcie@5,0 {
+ pcie5: pcie@5,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
reg = <0x2800 0 0 0 0>;
@@ -214,7 +214,7 @@
status = "disabled";
};
- pcie@6,0 {
+ pcie6: pcie@6,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
reg = <0x3000 0 0 0 0>;
@@ -231,7 +231,7 @@
status = "disabled";
};
- pcie@7,0 {
+ pcie7: pcie@7,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
reg = <0x3800 0 0 0 0>;
@@ -248,7 +248,7 @@
status = "disabled";
};
- pcie@8,0 {
+ pcie8: pcie@8,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
reg = <0x4000 0 0 0 0>;
@@ -265,7 +265,7 @@
status = "disabled";
};
- pcie@9,0 {
+ pcie9: pcie@9,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
reg = <0x4800 0 0 0 0>;
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index 0e24f1a38540..775bee53ce86 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -104,7 +104,7 @@
* configured as x4 or quad x1 lanes. Two units are
* x4/x1.
*/
- pcie-controller {
+ pciec: pcie-controller@82000000 {
compatible = "marvell,armada-xp-pcie";
status = "disabled";
device_type = "pci";
@@ -150,7 +150,7 @@
0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>;
- pcie@1,0 {
+ pcie1: pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
@@ -167,7 +167,7 @@
status = "disabled";
};
- pcie@2,0 {
+ pcie2: pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
@@ -184,7 +184,7 @@
status = "disabled";
};
- pcie@3,0 {
+ pcie3: pcie@3,0 {
device_type = "pci";
assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
@@ -201,7 +201,7 @@
status = "disabled";
};
- pcie@4,0 {
+ pcie4: pcie@4,0 {
device_type = "pci";
assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
@@ -218,7 +218,7 @@
status = "disabled";
};
- pcie@5,0 {
+ pcie5: pcie@5,0 {
device_type = "pci";
assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
reg = <0x2800 0 0 0 0>;
@@ -235,7 +235,7 @@
status = "disabled";
};
- pcie@6,0 {
+ pcie6: pcie@6,0 {
device_type = "pci";
assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
reg = <0x3000 0 0 0 0>;
@@ -252,7 +252,7 @@
status = "disabled";
};
- pcie@7,0 {
+ pcie7: pcie@7,0 {
device_type = "pci";
assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
reg = <0x3800 0 0 0 0>;
@@ -269,7 +269,7 @@
status = "disabled";
};
- pcie@8,0 {
+ pcie8: pcie@8,0 {
device_type = "pci";
assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
reg = <0x4000 0 0 0 0>;
@@ -286,7 +286,7 @@
status = "disabled";
};
- pcie@9,0 {
+ pcie9: pcie@9,0 {
device_type = "pci";
assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
reg = <0x4800 0 0 0 0>;
@@ -303,7 +303,7 @@
status = "disabled";
};
- pcie@10,0 {
+ pcie10: pcie@10,0 {
device_type = "pci";
assigned-addresses = <0x82005000 0 0x82000 0 0x2000>;
reg = <0x5000 0 0 0 0>;
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index d19f44c70925..a2f0e789465d 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -56,7 +56,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x00000000 0 0x80000000>; /* 2GB */
};
@@ -67,28 +67,6 @@
MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /* Connected to first Marvell 88SE9170 SATA controller */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /* Connected to second Marvell 88SE9170 SATA controller */
- pcie@2,0 {
- /* Port 0, Lane 1 */
- status = "okay";
- };
-
- /* Connected to Fresco Logic FL1009 USB 3.0 controller */
- pcie@5,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
/* RTC is provided by Intersil ISL12057 I2C RTC chip */
@@ -97,7 +75,6 @@
};
i2c@11000 {
- compatible = "marvell,mv64xxx-i2c";
clock-frequency = <400000>;
status = "okay";
@@ -154,23 +131,19 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 { /* Marvell 88E1318 */
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 { /* Marvell 88E1318 */
- reg = <1>;
- };
- };
-
ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
};
ethernet@74000 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
@@ -295,6 +268,39 @@
};
};
+&pciec {
+ status = "okay";
+
+ /* Connected to first Marvell 88SE9170 SATA controller */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /* Connected to second Marvell 88SE9170 SATA controller */
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
+ };
+
+ /* Connected to Fresco Logic FL1009 USB 3.0 controller */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1318 */
+ reg = <1>;
+ };
+};
+
+
&pinctrl {
poweroff: poweroff {
marvell,pins = "mpp42";
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index ed3b889d16ce..b577c9fb03a4 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -57,7 +57,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x00000000 0 0x40000000>; /* 1 GB soldered on */
};
@@ -98,15 +98,6 @@
};
};
- pcie-controller {
- status = "okay";
- /* Internal mini-PCIe connector */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
rtc@10300 {
/* No crystal connected to the internal RTC */
@@ -148,31 +139,13 @@
#address-cells = <1>;
#size-cells = <0>;
- button@1 {
+ init {
label = "Init Button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
};
};
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
-
- phy2: ethernet-phy@2 {
- reg = <2>;
- };
-
- phy3: ethernet-phy@3 {
- reg = <3>;
- };
- };
-
ethernet@70000 {
status = "okay";
phy = <&phy0>;
@@ -240,6 +213,33 @@
};
};
+&pciec {
+ status = "okay";
+ /* Internal mini-PCIe connector */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+};
+
&pinctrl {
led_pins: led-pins-0 {
marvell,pins = "mpp49", "mpp51", "mpp53";
diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
index ae286736b90a..e803da03146a 100644
--- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts
+++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -70,7 +70,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x00000000 0 0x40000000>; /* 1GB */
};
@@ -81,28 +81,6 @@
MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
- pcie-controller {
- status = "okay";
-
- /*
- * Connected to Marvell 88SX7042 SATA-II controller
- * handling the four disks.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /*
- * Connected to EtronTech EJ168A XHCI controller
- * providing the two rear USB 3.0 ports.
- */
- pcie@5,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
/* RTC is provided by Seiko S-35390A below */
@@ -150,16 +128,6 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 { /* Marvell 88E1512 */
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 { /* Marvell 88E1512 */
- reg = <1>;
- };
- };
-
ethernet@70000 {
status = "okay";
pinctrl-0 = <&ge0_rgmii_pins>;
@@ -186,7 +154,7 @@
&sata3_pwr_pin &sata4_pwr_pin>;
pinctrl-names = "default";
- sata1_regulator: sata1-regulator {
+ sata1_regulator: sata1-regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
regulator-name = "SATA1 Power";
@@ -199,7 +167,7 @@
gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- sata2_regulator: sata2-regulator {
+ sata2_regulator: sata2-regulator@2 {
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "SATA2 Power";
@@ -212,7 +180,7 @@
gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
};
- sata3_regulator: sata3-regulator {
+ sata3_regulator: sata3-regulator@3 {
compatible = "regulator-fixed";
reg = <3>;
regulator-name = "SATA3 Power";
@@ -225,7 +193,7 @@
gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
- sata4_regulator: sata4-regulator {
+ sata4_regulator: sata4-regulator@4 {
compatible = "regulator-fixed";
reg = <4>;
regulator-name = "SATA4 Power";
@@ -240,6 +208,39 @@
};
};
+&pciec {
+ status = "okay";
+
+ /*
+ * Connected to Marvell 88SX7042 SATA-II controller
+ * handling the four disks.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /*
+ * Connected to EtronTech EJ168A XHCI controller
+ * providing the two rear USB 3.0 ports.
+ */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+
+&mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1512 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1512 */
+ reg = <1>;
+ };
+};
+
&pinctrl {
sata1_pwr_pin: sata1-pwr-pin {
marvell,pins = "mpp42";
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 4a5f99e65b51..5274e4ff5d62 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -53,6 +53,9 @@
#include "armada-370-xp.dtsi"
/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
model = "Marvell Armada XP family SoC";
compatible = "marvell,armadaxp", "marvell,armada-370-xp";
@@ -75,7 +78,7 @@
reg = <0x1400 0x500>;
};
- L2: l2-cache {
+ L2: l2-cache@8000 {
compatible = "marvell,aurora-system-cache";
reg = <0x08000 0x1000>;
cache-id-part = <0x100>;
@@ -84,16 +87,6 @@
wt-override;
};
- i2c0: i2c@11000 {
- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11000 0x100>;
- };
-
- i2c1: i2c@11100 {
- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11100 0x100>;
- };
-
uart2: serial@12200 {
compatible = "snps,dw-apb-uart";
pinctrl-0 = <&uart2_pins>;
@@ -118,7 +111,7 @@
status = "disabled";
};
- system-controller@18200 {
+ systemc: system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0x18200 0x500>;
};
@@ -136,7 +129,7 @@
#clock-cells = <1>;
};
- thermal@182b0 {
+ thermal: thermal@182b0 {
compatible = "marvell,armadaxp-thermal";
reg = <0x182b0 0x4
0x184d0 0x4>;
@@ -150,27 +143,6 @@
clocks = <&coreclk 1>;
};
- interrupt-controller@20a00 {
- reg = <0x20a00 0x2d0>, <0x21070 0x58>;
- };
-
- timer@20300 {
- compatible = "marvell,armada-xp-timer";
- clocks = <&coreclk 2>, <&refclk>;
- clock-names = "nbclk", "fixed";
- };
-
- watchdog@20300 {
- compatible = "marvell,armada-xp-wdt";
- clocks = <&coreclk 2>, <&refclk>;
- clock-names = "nbclk", "fixed";
- };
-
- cpurst@20800 {
- compatible = "marvell,armada-370-cpu-reset";
- reg = <0x20800 0x20>;
- };
-
cpu-config@21000 {
compatible = "marvell,armada-xp-cpu-config";
reg = <0x21000 0x8>;
@@ -184,15 +156,7 @@
status = "disabled";
};
- usb@50000 {
- clocks = <&gateclk 18>;
- };
-
- usb@51000 {
- clocks = <&gateclk 19>;
- };
-
- usb@52000 {
+ usb2: usb@52000 {
compatible = "marvell,orion-ehci";
reg = <0x52000 0x500>;
interrupts = <47>;
@@ -200,7 +164,7 @@
status = "disabled";
};
- xor@60900 {
+ xor1: xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
0x60b00 0x100>;
@@ -228,7 +192,7 @@
compatible = "marvell,armada-xp-neta";
};
- crypto@90000 {
+ cesa: crypto@90000 {
compatible = "marvell,armada-xp-crypto";
reg = <0x90000 0x10000>;
reg-names = "regs";
@@ -248,7 +212,7 @@
status = "disabled";
};
- xor@f0900 {
+ xor0: xor@f0900 {
compatible = "marvell,orion-xor";
reg = <0xF0900 0x100
0xF0B00 0x100>;
@@ -309,6 +273,44 @@
};
};
+&i2c0 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x100>;
+};
+
+&i2c1 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x100>;
+};
+
+&mpic {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+};
+
+&timer {
+ compatible = "marvell,armada-xp-timer";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+};
+
+&watchdog {
+ compatible = "marvell,armada-xp-wdt";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+};
+
+&cpurst {
+ reg = <0x20800 0x20>;
+};
+
+&usb0 {
+ clocks = <&gateclk 18>;
+};
+
+&usb1 {
+ clocks = <&gateclk 19>;
+};
+
&pinctrl {
ge0_gmii_pins: ge0-gmii-pins {
marvell,pins =
diff --git a/arch/arm/boot/dts/artpec6-devboard.dts b/arch/arm/boot/dts/artpec6-devboard.dts
index f823ed382ac7..9dfe845694cf 100644
--- a/arch/arm/boot/dts/artpec6-devboard.dts
+++ b/arch/arm/boot/dts/artpec6-devboard.dts
@@ -46,6 +46,10 @@
status = "okay";
};
+&pcie {
+ status = "okay";
+};
+
&ethernet {
status = "okay";
diff --git a/arch/arm/boot/dts/artpec6.dtsi b/arch/arm/boot/dts/artpec6.dtsi
index 3489019cc0dc..767cbe8d8557 100644
--- a/arch/arm/boot/dts/artpec6.dtsi
+++ b/arch/arm/boot/dts/artpec6.dtsi
@@ -67,7 +67,7 @@
};
};
- syscon {
+ syscon: syscon@f8000000 {
compatible = "axis,artpec6-syscon", "syscon";
reg = <0xf8000000 0x48>;
};
@@ -154,6 +154,33 @@
interrupt-parent = <&intc>;
};
+ pcie: pcie@f8050000 {
+ compatible = "axis,artpec6-pcie", "snps,dw-pcie";
+ reg = <0xf8050000 0x2000
+ 0xf8040000 0x1000
+ 0xc0000000 0x2000>;
+ reg-names = "dbi", "phy", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ /* downstream I/O */
+ ranges = <0x81000000 0 0 0xc0002000 0 0x00010000
+ /* non-prefetchable memory */
+ 0x82000000 0 0xc0012000 0xc0012000 0 0x1ffee000>;
+ num-lanes = <2>;
+ bus-range = <0x00 0xff>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ axis,syscon-pcie = <&syscon>;
+ status = "disabled";
+ };
+
amba@0 {
compatible = "simple-bus";
#address-cells = <0x1>;
diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi
index a92c6e0ca854..b5a5a91bc2ef 100644
--- a/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi
@@ -12,8 +12,8 @@
#include "sama5d4.dtsi"
/ {
- model = "DENX MA5D4";
- compatible = "denx,ma5d4", "atmel,sama5d4", "atmel,sama5";
+ model = "Aries/DENX MA5D4";
+ compatible = "aries,ma5d4", "denx,ma5d4", "atmel,sama5d4", "atmel,sama5";
memory {
reg = <0x20000000 0x10000000>;
diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts
index eac4ea2744cc..84be29f38dae 100644
--- a/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts
+++ b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts
@@ -13,8 +13,8 @@
#include "at91-sama5d4_ma5d4.dtsi"
/ {
- model = "DENX MA5D4EVK";
- compatible = "denx,ma5d4evk", "atmel,sama5d4", "atmel,sama5";
+ model = "Aries/DENX MA5D4EVK";
+ compatible = "aries,ma5d4evk", "denx,ma5d4evk", "atmel,sama5d4", "atmel,sama5";
chosen {
stdout-path = "serial3:115200n8";
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index 4e913c2ccb79..f057e0b15a6f 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -481,8 +481,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA30 periph A */
- AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA31 periph with pullup */
+ <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index a3e363d79122..9e035b21e1b6 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -412,8 +412,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A */
- AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB15 periph with pullup */
+ <AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9260ek.dts b/arch/arm/boot/dts/at91sam9260ek.dts
index 2c87f58448e7..b2578feceb08 100644
--- a/arch/arm/boot/dts/at91sam9260ek.dts
+++ b/arch/arm/boot/dts/at91sam9260ek.dts
@@ -174,14 +174,14 @@
label = "Button 3";
gpios = <&pioA 30 GPIO_ACTIVE_LOW>;
linux,code = <0x103>;
- gpio-key,wakeup;
+ wakeup-source;
};
btn4 {
label = "Button 4";
gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
linux,code = <0x104>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index 32752d7883f1..3fe77c38bd0d 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -302,8 +302,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE>,
- <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index aeb1a36373f4..a1888f6d892b 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -412,8 +412,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC30 periph A */
- AT91_PIOC 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC31 periph with pullup */
+ <AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOC 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index b3501ae2a3bd..e567d5fd3f9d 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -478,8 +478,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A */
- AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB13 periph A */
+ <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 3b3eb3edcb47..f43d7695352d 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -500,8 +500,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A */
- AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA10 periph with pullup */
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index 70adf940d98c..f4c129a98f17 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -438,8 +438,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>,
- <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+ <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+ <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index ed4e4bd8a8f1..f66bae925705 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -460,8 +460,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A */
- AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PA10 periph A with pullup */
+ <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi
index fabc9f36c408..8833a4c3cd96 100644
--- a/arch/arm/boot/dts/bcm-cygnus.dtsi
+++ b/arch/arm/boot/dts/bcm-cygnus.dtsi
@@ -91,6 +91,13 @@
#address-cells = <1>;
#size-cells = <1>;
+ otp: otp@0301c800 {
+ compatible = "brcm,ocotp";
+ reg = <0x0301c800 0x2c>;
+ brcm,ocotp-size = <2048>;
+ status = "disabled";
+ };
+
pcie_phy: phy@0301d0a0 {
compatible = "brcm,cygnus-pcie-phy";
reg = <0x0301d0a0 0x14>;
@@ -108,12 +115,21 @@
};
};
- pinctrl: pinctrl@0x0301d0c8 {
+ pinctrl: pinctrl@0301d0c8 {
compatible = "brcm,cygnus-pinmux";
reg = <0x0301d0c8 0x30>,
<0x0301d24c 0x2c>;
};
+ mailbox: mailbox@03024024 {
+ compatible = "brcm,iproc-mailbox";
+ reg = <0x03024024 0x40>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ #mbox-cells = <1>;
+ };
+
gpio_crmu: gpio@03024800 {
compatible = "brcm,cygnus-crmu-gpio";
reg = <0x03024800 0x50>,
@@ -121,6 +137,9 @@
ngpios = <6>;
#gpio-cells = <2>;
gpio-controller;
+ interrupt-controller;
+ interrupt-parent = <&mailbox>;
+ interrupts = <0>;
};
i2c0: i2c@18008000 {
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 7c9e0fae9bb9..b6142bda661e 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -160,7 +160,7 @@
axi {
compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x0011ba08>;
+ ranges = <0x00000000 0x18000000 0x0011c40a>;
#address-cells = <1>;
#size-cells = <1>;
@@ -241,6 +241,16 @@
brcm,nand-has-wp;
};
+ gpiob: gpio@30000 {
+ compatible = "brcm,iproc-nsp-gpio", "brcm,iproc-gpio";
+ reg = <0x30000 0x50>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ ngpios = <4>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
pwm: pwm@31000 {
compatible = "brcm,iproc-pwm";
reg = <0x31000 0x28>;
@@ -254,6 +264,35 @@
reg = <0x33000 0x14>;
};
+ qspi: qspi@27200 {
+ compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi";
+ reg = <0x027200 0x184>,
+ <0x027000 0x124>,
+ <0x11c408 0x004>,
+ <0x0273a0 0x01c>;
+ reg-names = "mspi", "bspi", "intr_regs",
+ "intr_status_reg";
+ 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>,
+ <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "spi_lr_fullness_reached",
+ "spi_lr_session_aborted",
+ "spi_lr_impatient",
+ "spi_lr_session_done",
+ "spi_lr_overhead",
+ "mspi_done",
+ "mspi_halted";
+ clocks = <&iprocmed>;
+ clock-names = "iprocmed";
+ num-cs = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
ccbtimer0: timer@34000 {
compatible = "arm,sp804";
reg = <0x34000 0x1000>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index f7f9db355d98..d0704540db6b 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -22,7 +22,72 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
+ /*
+ * This is based on the unreleased schematic for the Model A+.
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "SDA0",
+ "SCL0",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "GPIO5",
+ "GPIO6",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "GPIO12",
+ "GPIO13",
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "GPIO16",
+ "GPIO17",
+ "GPIO18",
+ "GPIO19",
+ "GPIO20",
+ "GPIO21",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "GPIO26",
+ "GPIO27",
+ "SDA0",
+ "SCL0",
+ "NC", /* GPIO30 */
+ "NC", /* GPIO31 */
+ "CAM_GPIO1", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "PWR_LOW_N", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "USB_LIMIT", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "PWM0_OUT", /* GPIO40 */
+ "CAM_GPIO0", /* GPIO41 */
+ "NC", /* GPIO42 */
+ "NC", /* GPIO43 */
+ "NC", /* GPIO44 */
+ "PWM1_OUT", /* GPIO45 */
+ "HDMI_HPD_N",
+ "STATUS_LED",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>;
/* I2S interface */
i2s_alt0: i2s_alt0 {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 8be102f5d826..46d078e29017 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -15,7 +15,74 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
+ /*
+ * Taken from Raspberry-Pi-Rev-1.0-Model-AB-Schematics.pdf
+ * RPI00021 sheet 02
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "SDA0",
+ "SCL0",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "CAM_GPIO1",
+ "LAN_RUN",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "NC", /* GPIO12 */
+ "NC", /* GPIO13 */
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "STATUS_LED_N",
+ "GPIO17",
+ "GPIO18",
+ "NC", /* GPIO19 */
+ "NC", /* GPIO20 */
+ "GPIO21",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "NC", /* GPIO26 */
+ "CAM_GPIO0",
+ /* Binary number representing build/revision */
+ "CONFIG0",
+ "CONFIG1",
+ "CONFIG2",
+ "CONFIG3",
+ "NC", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "NC", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "NC", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "PWM0_OUT",
+ "NC", /* GPIO41 */
+ "NC", /* GPIO42 */
+ "NC", /* GPIO43 */
+ "NC", /* GPIO44 */
+ "PWM1_OUT",
+ "HDMI_HPD_P",
+ "SD_CARD_DET",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt2>;
/* I2S interface */
i2s_alt2: i2s_alt2 {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 35cde65c975e..432088ebb0a1 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -23,7 +23,73 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
+ /*
+ * Taken from Raspberry-Pi-B-Plus-V1.2-Schematics.pdf
+ * RPI-BPLUS sheet 1
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "SDA0",
+ "SCL0",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "GPIO5",
+ "GPIO6",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "GPIO12",
+ "GPIO13",
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "GPIO16",
+ "GPIO17",
+ "GPIO18",
+ "GPIO19",
+ "GPIO20",
+ "GPIO21",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "GPIO26",
+ "GPIO27",
+ "SDA0",
+ "SCL0",
+ "NC", /* GPIO30 */
+ "LAN_RUN", /* GPIO31 */
+ "CAM_GPIO1", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "PWR_LOW_N", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "USB_LIMIT", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "PWM0_OUT", /* GPIO40 */
+ "CAM_GPIO0", /* GPIO41 */
+ "NC", /* GPIO42 */
+ "NC", /* GPIO43 */
+ "ETHCLK", /* GPIO44 */
+ "PWM1_OUT", /* GPIO45 */
+ "HDMI_HPD_N",
+ "STATUS_LED",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>;
/* I2S interface */
i2s_alt0: i2s_alt0 {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index 84df85ea6296..4133bc2cd9be 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -16,7 +16,73 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
+ /*
+ * Taken from Raspberry-Pi-Rev-2.0-Model-AB-Schematics.pdf
+ * RPI00022 sheet 02
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "SDA0",
+ "SCL0",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "CAM_CLK",
+ "LAN_RUN",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "NC", /* GPIO12 */
+ "NC", /* GPIO13 */
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "STATUS_LED_N",
+ "GPIO17",
+ "GPIO18",
+ "NC", /* GPIO19 */
+ "NC", /* GPIO20 */
+ "CAM_GPIO",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "NC", /* GPIO26 */
+ "GPIO27",
+ "GPIO28",
+ "GPIO29",
+ "GPIO30",
+ "GPIO31",
+ "NC", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "NC", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "NC", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "PWM0_OUT",
+ "NC", /* GPIO41 */
+ "NC", /* GPIO42 */
+ "NC", /* GPIO43 */
+ "NC", /* GPIO44 */
+ "PWM1_OUT",
+ "HDMI_HPD_P",
+ "SD_CARD_DET",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt2>;
/* I2S interface */
i2s_alt2: i2s_alt2 {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 8e626a80fe24..4d56fe3006b0 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -16,7 +16,74 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &alt3>;
+ /*
+ * Taken from Raspberry-Pi-Rev-1.0-Model-AB-Schematics.pdf
+ * RPI00021 sheet 02
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "SDA0",
+ "SCL0",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "CAM_GPIO1",
+ "LAN_RUN",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "NC", /* GPIO12 */
+ "NC", /* GPIO13 */
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "STATUS_LED_N",
+ "GPIO17",
+ "GPIO18",
+ "NC", /* GPIO19 */
+ "NC", /* GPIO20 */
+ "GPIO21",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "NC", /* GPIO26 */
+ "CAM_GPIO0",
+ /* Binary number representing build/revision */
+ "CONFIG0",
+ "CONFIG1",
+ "CONFIG2",
+ "CONFIG3",
+ "NC", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "NC", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "NC", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "PWM0_OUT",
+ "NC", /* GPIO41 */
+ "NC", /* GPIO42 */
+ "NC", /* GPIO43 */
+ "NC", /* GPIO44 */
+ "PWM1_OUT",
+ "HDMI_HPD_P",
+ "SD_CARD_DET",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0>;
};
&hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero.dts b/arch/arm/boot/dts/bcm2835-rpi-zero.dts
index 60e359fafc5b..cc8b832c4c78 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero.dts
@@ -26,7 +26,72 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
+ /*
+ * This is based on the official GPU firmware DT blob.
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "SDA0",
+ "SCL0",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "GPIO5",
+ "GPIO6",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "GPIO12",
+ "GPIO13",
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "GPIO16",
+ "GPIO17",
+ "GPIO18",
+ "GPIO19",
+ "GPIO20",
+ "GPIO21",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "GPIO26",
+ "GPIO27",
+ "SDA0",
+ "SCL0",
+ "NC", /* GPIO30 */
+ "NC", /* GPIO31 */
+ "CAM_GPIO1", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "NC", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "NC", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "NC", /* GPIO40 */
+ "CAM_GPIO0", /* GPIO41 */
+ "NC", /* GPIO42 */
+ "NC", /* GPIO43 */
+ "NC", /* GPIO44 */
+ "NC", /* GPIO45 */
+ "HDMI_HPD_N",
+ "STATUS_LED_N",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>;
/* I2S interface */
i2s_alt0: i2s_alt0 {
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e9b47b2bbc33..6ddf7dfe3f72 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -39,22 +39,21 @@
};
alt0: alt0 {
- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>;
+ brcm,pins = <4 5 7 8 9 10 11 14 15>;
brcm,function = <BCM2835_FSEL_ALT0>;
};
-
- alt3: alt3 {
- brcm,pins = <48 49 50 51 52 53>;
- brcm,function = <BCM2835_FSEL_ALT3>;
- };
};
&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_gpio0>;
status = "okay";
clock-frequency = <100000>;
};
&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_gpio2>;
status = "okay";
clock-frequency = <100000>;
};
@@ -64,11 +63,15 @@
};
&sdhci {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_gpio48>;
status = "okay";
bus-width = <4>;
};
&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio45>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index a78759e73710..0890d97e674d 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -23,3 +23,9 @@
};
};
};
+
+/* enable thermal sensor with the correct compatible property set */
+&thermal {
+ compatible = "brcm,bcm2835-thermal";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 39dccf62ac96..bf19e8cfb9e6 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -27,7 +27,7 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>;
/* I2S interface */
i2s_alt0: i2s_alt0 {
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
index 9d0651d8f373..519a44f5d25a 100644
--- a/arch/arm/boot/dts/bcm2836.dtsi
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -76,3 +76,9 @@
interrupt-parent = <&local_intc>;
interrupts = <8>;
};
+
+/* enable thermal sensor with the correct compatible property set */
+&thermal {
+ compatible = "brcm,bcm2836-thermal";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 46d46d894a44..9a44da190897 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -104,7 +104,7 @@
reg = <0x7e104000 0x10>;
};
- mailbox: mailbox@7e00b800 {
+ mailbox: mailbox@7e00b880 {
compatible = "brcm,bcm2835-mbox";
reg = <0x7e00b880 0x40>;
interrupts = <0 1>;
@@ -132,6 +132,209 @@
interrupt-controller;
#interrupt-cells = <2>;
+
+ /* Defines pin muxing groups according to
+ * BCM2835-ARM-Peripherals.pdf page 102.
+ *
+ * While each pin can have its mux selected
+ * for various functions individually, some
+ * groups only make sense to switch to a
+ * particular function together.
+ */
+ dpi_gpio0: dpi_gpio0 {
+ brcm,pins = <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>;
+ brcm,function = <BCM2835_FSEL_ALT2>;
+ };
+ emmc_gpio22: emmc_gpio22 {
+ brcm,pins = <22 23 24 25 26 27>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+ emmc_gpio34: emmc_gpio34 {
+ brcm,pins = <34 35 36 37 38 39>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ brcm,pull = <BCM2835_PUD_OFF
+ BCM2835_PUD_UP
+ BCM2835_PUD_UP
+ BCM2835_PUD_UP
+ BCM2835_PUD_UP
+ BCM2835_PUD_UP>;
+ };
+ emmc_gpio48: emmc_gpio48 {
+ brcm,pins = <48 49 50 51 52 53>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+
+ gpclk0_gpio4: gpclk0_gpio4 {
+ brcm,pins = <4>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ gpclk1_gpio5: gpclk1_gpio5 {
+ brcm,pins = <5>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ gpclk1_gpio42: gpclk1_gpio42 {
+ brcm,pins = <42>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ gpclk1_gpio44: gpclk1_gpio44 {
+ brcm,pins = <44>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ gpclk2_gpio6: gpclk2_gpio6 {
+ brcm,pins = <6>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ gpclk2_gpio43: gpclk2_gpio43 {
+ brcm,pins = <43>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+
+ i2c0_gpio0: i2c0_gpio0 {
+ brcm,pins = <0 1>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ i2c0_gpio32: i2c0_gpio32 {
+ brcm,pins = <32 34>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ i2c0_gpio44: i2c0_gpio44 {
+ brcm,pins = <44 45>;
+ brcm,function = <BCM2835_FSEL_ALT1>;
+ };
+ i2c1_gpio2: i2c1_gpio2 {
+ brcm,pins = <2 3>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ i2c1_gpio44: i2c1_gpio44 {
+ brcm,pins = <44 45>;
+ brcm,function = <BCM2835_FSEL_ALT2>;
+ };
+ i2c_slave_gpio18: i2c_slave_gpio18 {
+ brcm,pins = <18 19 20 21>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+
+ jtag_gpio4: jtag_gpio4 {
+ brcm,pins = <4 5 6 12 13>;
+ brcm,function = <BCM2835_FSEL_ALT4>;
+ };
+ jtag_gpio22: jtag_gpio22 {
+ brcm,pins = <22 23 24 25 26 27>;
+ brcm,function = <BCM2835_FSEL_ALT4>;
+ };
+
+ pcm_gpio18: pcm_gpio18 {
+ brcm,pins = <18 19 20 21>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pcm_gpio28: pcm_gpio28 {
+ brcm,pins = <28 29 30 31>;
+ brcm,function = <BCM2835_FSEL_ALT2>;
+ };
+
+ pwm0_gpio12: pwm0_gpio12 {
+ brcm,pins = <12>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm0_gpio18: pwm0_gpio18 {
+ brcm,pins = <18>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ pwm0_gpio40: pwm0_gpio40 {
+ brcm,pins = <40>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm1_gpio13: pwm1_gpio13 {
+ brcm,pins = <13>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm1_gpio19: pwm1_gpio19 {
+ brcm,pins = <19>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ pwm1_gpio41: pwm1_gpio41 {
+ brcm,pins = <41>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm1_gpio45: pwm1_gpio45 {
+ brcm,pins = <45>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+
+ sdhost_gpio48: sdhost_gpio48 {
+ brcm,pins = <48 49 50 51 52 53>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+
+ spi0_gpio7: spi0_gpio7 {
+ brcm,pins = <7 8 9 10 11>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ spi0_gpio35: spi0_gpio35 {
+ brcm,pins = <35 36 37 38 39>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ spi1_gpio16: spi1_gpio16 {
+ brcm,pins = <16 17 18 19 20 21>;
+ brcm,function = <BCM2835_FSEL_ALT4>;
+ };
+ spi2_gpio40: spi2_gpio40 {
+ brcm,pins = <40 41 42 43 44 45>;
+ brcm,function = <BCM2835_FSEL_ALT4>;
+ };
+
+ uart0_gpio14: uart0_gpio14 {
+ brcm,pins = <14 15>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ /* Separate from the uart0_gpio14 group
+ * because it conflicts with spi1_gpio16, and
+ * people often run uart0 on the two pins
+ * without flow contrl.
+ */
+ uart0_ctsrts_gpio16: uart0_ctsrts_gpio16 {
+ brcm,pins = <16 17>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+ uart0_gpio30: uart0_gpio30 {
+ brcm,pins = <30 31>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+ uart0_ctsrts_gpio32: uart0_ctsrts_gpio32 {
+ brcm,pins = <32 33>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+
+ uart1_gpio14: uart1_gpio14 {
+ brcm,pins = <14 15>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ uart1_ctsrts_gpio16: uart1_ctsrts_gpio16 {
+ brcm,pins = <16 17>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ uart1_gpio32: uart1_gpio32 {
+ brcm,pins = <32 33>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ uart1_ctsrts_gpio30: uart1_ctsrts_gpio30 {
+ brcm,pins = <30 31>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ uart1_gpio36: uart1_gpio36 {
+ brcm,pins = <36 37 38 39>;
+ brcm,function = <BCM2835_FSEL_ALT2>;
+ };
+ uart1_gpio40: uart1_gpio40 {
+ brcm,pins = <40 41>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ uart1_ctsrts_gpio42: uart1_ctsrts_gpio42 {
+ brcm,pins = <42 43>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
};
uart0: serial@7e201000 {
@@ -187,6 +390,13 @@
interrupts = <2 14>; /* pwa1 */
};
+ thermal: thermal@7e212000 {
+ compatible = "brcm,bcm2835-thermal";
+ reg = <0x7e212000 0x8>;
+ clocks = <&clocks BCM2835_CLOCK_TSENS>;
+ status = "disabled";
+ };
+
aux: aux@0x7e215000 {
compatible = "brcm,bcm2835-aux";
#clock-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
new file mode 100644
index 000000000000..35e6ed6a3ef7
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Luxul Inc.
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "luxul,xap-1510v1", "brcm,bcm4708";
+ model = "Luxul XAP-1510 V1";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ 5ghz {
+ label = "bcm53xx:blue:5ghz";
+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+
+ 2ghz {
+ label = "bcm53xx:blue:2ghz";
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ };
+
+ status {
+ label = "bcm53xx:green:status";
+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "timer";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&spi_nor {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
index 8ade7def2e8a..eac0f52e5ebd 100644
--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
@@ -9,7 +9,7 @@
/dts-v1/;
-#include "bcm4708.dtsi"
+#include "bcm4709.dtsi"
#include "bcm5301x-nand-cs0-bch8.dtsi"
/ {
diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
index 0653e7ef248c..aab39c9864da 100644
--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
@@ -9,7 +9,7 @@
/dts-v1/;
-#include "bcm4708.dtsi"
+#include "bcm4709.dtsi"
#include "bcm5301x-nand-cs0-bch8.dtsi"
/ {
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
index a22ed144040b..fd38d2aa3521 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
@@ -9,7 +9,7 @@
/dts-v1/;
-#include "bcm4708.dtsi"
+#include "bcm4709.dtsi"
#include "bcm5301x-nand-cs0-bch8.dtsi"
/ {
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
index ca181516c28a..92f8a7219e98 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
@@ -9,7 +9,7 @@
/dts-v1/;
-#include "bcm4708.dtsi"
+#include "bcm4709.dtsi"
#include "bcm5301x-nand-cs0-bch8.dtsi"
/ {
@@ -107,6 +107,10 @@
};
};
+&uart0 {
+ status = "okay";
+};
+
&usb2 {
vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
new file mode 100644
index 000000000000..9a92c24ac2d8
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm4709.dtsi"
+
+/ {
+ compatible = "tplink,archer-c9-v1", "brcm,bcm4709", "brcm,bcm4708";
+ model = "TP-LINK Archer C9 V1";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ lan {
+ label = "bcm53xx:blue:lan";
+ gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wps {
+ label = "bcm53xx:blue:wps";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ 2ghz {
+ label = "bcm53xx:blue:2ghz";
+ gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz {
+ label = "bcm53xx:blue:5ghz";
+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb3 {
+ label = "bcm53xx:blue:usb3";
+ gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb2 {
+ label = "bcm53xx:blue:usb2";
+ gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan-blue {
+ label = "bcm53xx:blue:wan";
+ gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan-amber {
+ label = "bcm53xx:amber:wan";
+ gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ power {
+ label = "bcm53xx:blue:power";
+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb2 {
+ vcc-gpio = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
+};
+
+&usb3 {
+ vcc-gpio = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
+};
+
+&spi_nor {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm4709.dtsi b/arch/arm/boot/dts/bcm4709.dtsi
new file mode 100644
index 000000000000..f03976597a6d
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4709.dtsi
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
+ *
+ * Licensed under the ISC license.
+ */
+
+#include "bcm4708.dtsi"
+
+&uart0 {
+ clock-frequency = <125000000>;
+};
diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
index c8c0b3616935..661348dbb7ce 100644
--- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
@@ -9,7 +9,7 @@
/dts-v1/;
-#include "bcm4708.dtsi"
+#include "bcm47094.dtsi"
#include "bcm5301x-nand-cs0-bch1.dtsi"
/ {
@@ -107,7 +107,6 @@
&uart0 {
status = "okay";
- clock-frequency = <125000000>;
};
&usb3 {
diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
new file mode 100644
index 000000000000..169b35fe5651
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Luxul Inc.
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm47094.dtsi"
+#include "bcm5301x-nand-cs0-bch4.dtsi"
+
+/ {
+ compatible = "luxul,xwr-3100v1", "brcm,bcm47094", "brcm,bcm4708";
+ model = "Luxul XWR-3100 V1";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power {
+ label = "bcm53xx:green:power";
+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ lan3 {
+ label = "bcm53xx:green:lan1";
+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ lan4 {
+ label = "bcm53xx:green:lan0";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan {
+ label = "bcm53xx:green:wan";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ lan1 {
+ label = "bcm53xx:green:lan3";
+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ lan2 {
+ label = "bcm53xx:green:lan2";
+ gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb3 {
+ label = "bcm53xx:green:usb3";
+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ status {
+ label = "bcm53xx:green:status";
+ gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "timer";
+ };
+
+ 2ghz {
+ label = "bcm53xx:green:2ghz";
+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz {
+ label = "bcm53xx:green:5ghz";
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb3 {
+ vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
+};
+
+&spi_nor {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
new file mode 100644
index 000000000000..521b4155de60
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm47094.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+/ {
+ compatible = "netgear,r8500", "brcm,bcm47094", "brcm,bcm4708";
+ model = "Netgear R8500";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power0 {
+ label = "bcm53xx:white:power";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ power1 {
+ label = "bcm53xx:amber:power";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz-1 {
+ label = "bcm53xx:white:5ghz-1";
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz-2 {
+ label = "bcm53xx:white:5ghz-2";
+ gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 2ghz {
+ label = "bcm53xx:white:2ghz";
+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb2 {
+ label = "bcm53xx:white:usb2";
+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb3 {
+ label = "bcm53xx:white:usb3";
+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ brightness {
+ label = "Backlight";
+ linux,code = <KEY_BRIGHTNESS_ZERO>;
+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+ };
+
+ rfkill {
+ label = "WiFi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm47094.dtsi b/arch/arm/boot/dts/bcm47094.dtsi
new file mode 100644
index 000000000000..4f09aa0114e6
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47094.dtsi
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
+ *
+ * Licensed under the ISC license.
+ */
+
+#include "bcm4708.dtsi"
+
+/ {
+ usb3_phy: usb3-phy {
+ compatible = "brcm,ns-bx-usb3-phy";
+ };
+};
+
+&uart0 {
+ clock-frequency = <125000000>;
+};
diff --git a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
new file mode 100644
index 000000000000..4403ae8790c2
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm53573.dtsi"
+
+/ {
+ compatible = "tenda,ac9", "brcm,bcm47189", "brcm,bcm53573";
+ model = "Tenda AC9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ usb {
+ label = "bcm53xx:blue:usb";
+ gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wps {
+ label = "bcm53xx:blue:wps";
+ gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz {
+ label = "bcm53xx:blue:5ghz";
+ gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ system {
+ label = "bcm53xx:blue:system";
+ gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "timer";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rfkill {
+ label = "WiFi";
+ linux,code = <KEY_RFKILL>;
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ };
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm5301x-nand-cs0-bch4.dtsi b/arch/arm/boot/dts/bcm5301x-nand-cs0-bch4.dtsi
new file mode 100644
index 000000000000..b4e875df9528
--- /dev/null
+++ b/arch/arm/boot/dts/bcm5301x-nand-cs0-bch4.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2016 Luxul Inc.
+ *
+ * Licensed under the ISC license.
+ */
+
+#include "bcm5301x-nand-cs0.dtsi"
+
+&nandcs {
+ nand-ecc-algo = "bch";
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+};
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
index ae4b3880616d..f09a2bb08979 100644
--- a/arch/arm/boot/dts/bcm5301x.dtsi
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
@@ -149,6 +149,13 @@
clock-names = "phy-ref-clk";
};
+ usb3_phy: usb3-phy {
+ compatible = "brcm,ns-ax-usb3-phy";
+ reg = <0x18105000 0x1000>, <0x18003000 0x1000>;
+ reg-names = "dmp", "ccb-mii";
+ #phy-cells = <0>;
+ };
+
axi@18000000 {
compatible = "brcm,bus-axi";
reg = <0x18000000 0x1000>;
diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi
new file mode 100644
index 000000000000..e2c496a96c32
--- /dev/null
+++ b/arch/arm/boot/dts/bcm53573.dtsi
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
+ *
+ * Licensed under the ISC license.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ };
+ };
+
+ mpcore {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x18310000 0x00008000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gic: interrupt-controller@1000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x1000 0x1000>,
+ <0x2000 0x0100>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ alp: oscillator {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ };
+ };
+
+ axi@18000000 {
+ compatible = "brcm,bus-axi";
+ reg = <0x18000000 0x1000>;
+ ranges = <0x00000000 0x18000000 0x00100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0x000fffff 0xffff>;
+ interrupt-map =
+ /* ChipCommon */
+ <0x00000000 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* IEEE 802.11 0 */
+ <0x00001000 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* PCIe Controller 0 */
+ <0x00002000 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00002000 1 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00002000 2 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00002000 3 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00002000 4 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0x00002000 5 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* USB 2.0 Controller */
+ <0x00004000 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* Ethernet Controller 0 */
+ <0x00005000 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* IEEE 802.11 1 */
+ <0x0000a000 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+
+ /* Ethernet Controller 1 */
+ <0x0000b000 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+
+ chipcommon: chipcommon@0 {
+ compatible = "simple-bus";
+ reg = <0x00000000 0x1000>;
+ ranges;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ uart0: serial@0300 {
+ compatible = "ns16550a";
+ reg = <0x0300 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&alp>;
+ status = "okay";
+ };
+ };
+
+ usb2: usb2@4000 {
+ reg = <0x4000 0x1000>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ehci: ehci@4000 {
+ compatible = "generic-ehci";
+ reg = <0x4000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ohci: ohci@d000 {
+ #usb-cells = <0>;
+
+ compatible = "generic-ohci";
+ reg = <0xd000 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gmac0: ethernet@5000 {
+ reg = <0x5000 0x1000>;
+ };
+
+ gmac1: ethernet@b000 {
+ reg = <0xb000 0x1000>;
+ };
+
+ pmu@12000 {
+ compatible = "simple-mfd", "syscon";
+ reg = <0x00012000 0x00001000>;
+
+ ilp: ilp {
+ compatible = "brcm,bcm53573-ilp";
+ clocks = <&alp>;
+ #clock-cells = <0>;
+ clock-output-names = "ilp";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
index 05c5f98c8782..59d96fb91583 100644
--- a/arch/arm/boot/dts/bcm958625k.dts
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -139,3 +139,37 @@
groups = "nand_grp";
};
};
+
+&qspi {
+ bspi-sel = <0>;
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p80";
+ reg = <0x0>;
+ spi-max-frequency = <12500000>;
+ m25p,fast-read;
+ spi-cpol;
+ spi-cpha;
+
+ partition@0 {
+ label = "boot";
+ reg = <0x00000000 0x000a0000>;
+ };
+
+ partition@a0000 {
+ label = "env";
+ reg = <0x000a0000 0x00060000>;
+ };
+
+ partition@100000 {
+ label = "system";
+ reg = <0x00100000 0x00600000>;
+ };
+
+ partition@700000 {
+ label = "rootfs";
+ reg = <0x00700000 0x01900000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
index f485308840ab..57aa5f8a7c77 100644
--- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
+++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
@@ -48,7 +48,7 @@
reg = <0x00000000 0x80000000>;
};
- choosen {
+ chosen {
bootargs = "earlyprintk";
stdout-path = "serial0:115200n8";
};
@@ -58,7 +58,7 @@
#address-cells = <1>;
#size-cells = <0>;
- reg_usb0_vbus: regulator@0 {
+ reg_usb0_vbus: regulator_usb0 {
compatible = "regulator-fixed";
regulator-name = "usb0_vbus";
regulator-min-microvolt = <5000000>;
@@ -67,7 +67,7 @@
enable-active-high;
};
- reg_usb1_vbus: regulator@1 {
+ reg_usb1_vbus: regulator_usb1 {
compatible = "regulator-fixed";
regulator-name = "usb1_vbus";
regulator-min-microvolt = <5000000>;
@@ -76,7 +76,7 @@
enable-active-high;
};
- reg_usb2_vbus: regulator@2 {
+ reg_usb2_vbus: regulator_usb2 {
compatible = "regulator-fixed";
regulator-name = "usb2_vbus";
regulator-min-microvolt = <5000000>;
@@ -85,7 +85,7 @@
enable-active-high;
};
- reg_sdio1_vmmc: regulator@3 {
+ reg_sdio1_vmmc: regulator_sdio1_vmmc {
compatible = "regulator-fixed";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -95,7 +95,7 @@
gpio = <&portb 21 GPIO_ACTIVE_HIGH>;
};
- reg_sdio1_vqmmc: regulator@4 {
+ reg_sdio1_vqmmc: regulator_sido1_vqmmc {
compatible = "regulator-gpio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts b/arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
new file mode 100644
index 000000000000..bfde32e37123
--- /dev/null
+++ b/arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
@@ -0,0 +1,94 @@
+/*
+ * cloudengines-pogoplug-series-3.dtsi - Device tree file for Cloud Engines PogoPlug Series 3
+ *
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+#include "ox820.dtsi"
+
+/ {
+ model = "Cloud Engines PogoPlug Series 3";
+
+ compatible = "cloudengines,pogoplugv3", "oxsemi,ox820";
+
+ chosen {
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ /* 128Mbytes DDR */
+ reg = <0x60000000 0x8000000>;
+ };
+
+ aliases {
+ serial0 = &uart0;
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ blue {
+ label = "pogoplug:blue";
+ gpios = <&gpio0 2 0>;
+ default-state = "keep";
+ };
+
+ orange {
+ label = "pogoplug:orange";
+ gpios = <&gpio1 16 1>;
+ default-state = "keep";
+ };
+
+ green {
+ label = "pogoplug:green";
+ gpios = <&gpio1 17 1>;
+ default-state = "keep";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+};
+
+&nandc {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+
+ nand@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ nand-ecc-mode = "soft";
+ nand-ecc-algo = "hamming";
+
+ partition@0 {
+ label = "boot";
+ reg = <0x00000000 0x00e00000>;
+ read-only;
+ };
+
+ partition@e00000 {
+ label = "ubi";
+ reg = <0x00e00000 0x07200000>;
+ };
+ };
+};
+
+&etha {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_etha_mdio>;
+};
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 7b8ab21fed6c..afcb4821deb1 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -13,6 +13,7 @@
aliases {
serial2 = &serial2;
+ ethernet0 = &eth0;
};
chosen {
@@ -122,7 +123,7 @@
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins>;
- cd-gpios = <&gpio 64 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio 64 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -158,6 +159,14 @@
rx-num-evt = <32>;
};
+&usb_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
&aemif {
pinctrl-names = "default";
pinctrl-0 = <&nand_pins>;
@@ -219,3 +228,11 @@
};
};
};
+
+&prictrl {
+ status = "okay";
+};
+
+&memctrl {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index f79e1b91c680..104155d12c2f 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -36,6 +36,7 @@
reg = <0x14120 0x50>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <2>;
pinctrl-single,bit-per-mux;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0xf>;
@@ -186,8 +187,44 @@
0xc 0x88888888 0xffffffff
>;
};
+ lcd_pins: pinmux_lcd_pins {
+ pinctrl-single,bits = <
+ /*
+ * LCD_D[2], LCD_D[3], LCD_D[4], LCD_D[5],
+ * LCD_D[6], LCD_D[7]
+ */
+ 0x40 0x22222200 0xffffff00
+ /*
+ * LCD_D[10], LCD_D[11], LCD_D[12], LCD_D[13],
+ * LCD_D[14], LCD_D[15], LCD_D[0], LCD_D[1]
+ */
+ 0x44 0x22222222 0xffffffff
+ /* LCD_D[8], LCD_D[9] */
+ 0x48 0x00000022 0x000000ff
+
+ /* LCD_PCLK */
+ 0x48 0x02000000 0x0f000000
+ /* LCD_AC_ENB_CS, LCD_VSYNC, LCD_HSYNC */
+ 0x4c 0x02000022 0x0f0000ff
+ >;
+ };
};
+ prictrl: priority-controller@14110 {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+ status = "disabled";
+ };
+ cfgchip: chip-controller@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ usb_phy: usb-phy {
+ compatible = "ti,da830-usb-phy";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+ };
edma0: edma@0 {
compatible = "ti,edma3-tpcc";
/* eDMA3 CC0: 0x01c0 0000 - 0x01c0 7fff */
@@ -280,6 +317,8 @@
mmc0: mmc@40000 {
compatible = "ti,da830-mmc";
reg = <0x40000 0x1000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
interrupts = <16>;
dmas = <&edma0 16 0>, <&edma0 17 0>;
dma-names = "rx", "tx";
@@ -288,6 +327,8 @@
mmc1: mmc@21b000 {
compatible = "ti,da830-mmc";
reg = <0x21b000 0x1000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
interrupts = <72>;
dmas = <&edma1 28 0>, <&edma1 29 0>;
dma-names = "rx", "tx";
@@ -336,6 +377,8 @@
num-cs = <6>;
ti,davinci-spi-intr-line = <1>;
interrupts = <20>;
+ dmas = <&edma0 14 0>, <&edma0 15 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
spi1: spi@30e000 {
@@ -350,6 +393,16 @@
dma-names = "rx", "tx";
status = "disabled";
};
+ usb0: usb@200000 {
+ compatible = "ti,da830-musb";
+ reg = <0x200000 0x10000>;
+ interrupts = <58>;
+ interrupt-names = "mc";
+ dr_mode = "otg";
+ phys = <&usb_phy 0>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
mdio: mdio@224000 {
compatible = "ti,davinci_mdio";
#address-cells = <1>;
@@ -386,6 +439,11 @@
ti,davinci-gpio-unbanked = <0>;
status = "disabled";
};
+ pinconf: pin-controller@22c00c {
+ compatible = "ti,da850-pupd";
+ reg = <0x22c00c 0x8>;
+ status = "disabled";
+ };
mcasp0: mcasp@100000 {
compatible = "ti,da830-mcasp-audio";
@@ -399,6 +457,13 @@
<&edma0 0 1>;
dma-names = "tx", "rx";
};
+
+ display: display@213000 {
+ compatible = "ti,da850-tilcdc";
+ reg = <0x213000 0x1000>;
+ interrupts = <52>;
+ status = "disabled";
+ };
};
aemif: aemif@68000000 {
compatible = "ti,da850-aemif";
@@ -410,4 +475,9 @@
1 0 0x68000000 0x00008000>;
status = "disabled";
};
+ memctrl: memory-controller@b0000000 {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi
index ff90a6ce6bdc..1facc5f12cef 100644
--- a/arch/arm/boot/dts/dm814x.dtsi
+++ b/arch/arm/boot/dts/dm814x.dtsi
@@ -373,6 +373,7 @@
reg = <0x800 0x438>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x307ff>;
};
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
index f1e0f771ff29..61dd2f6b02bc 100644
--- a/arch/arm/boot/dts/dm816x.dtsi
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -83,6 +83,7 @@
reg = <0x48140000 0x21000>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
ranges = <0 0x48140000 0x21000>;
dm816x_pinmux: pinmux@800 {
@@ -90,6 +91,7 @@
reg = <0x800 0x50a>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <16>;
pinctrl-single,function-mask = <0xf>;
};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index d4fcd68f6349..addb7530cfbe 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -171,6 +171,7 @@
reg = <0x1400 0x0468>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <32>;
diff --git a/arch/arm/boot/dts/dra71-evm.dts b/arch/arm/boot/dts/dra71-evm.dts
new file mode 100644
index 000000000000..2b9a5a8d69ad
--- /dev/null
+++ b/arch/arm/boot/dts/dra71-evm.dts
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "dra72-evm-common.dtsi"
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+ compatible = "ti,dra718-evm", "ti,dra718", "ti,dra722", "ti,dra72", "ti,dra7";
+ model = "TI DRA718 EVM";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x80000000>; /* 2GB */
+ };
+
+ vpo_sd_1v8_3v3: gpio-regulator-TPS74801 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "vddshv8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ vin-supply = <&evm_5v0>;
+
+ gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+ states = <1800000 0x0
+ 3000000 0x1>;
+ };
+
+ poweroff: gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio7 30 GPIO_ACTIVE_HIGH>;
+ input;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ lp8733: lp8733@60 {
+ compatible = "ti,lp8733";
+ reg = <0x60>;
+
+ buck0-in-supply =<&vsys_3v3>;
+ buck1-in-supply =<&vsys_3v3>;
+ ldo0-in-supply =<&evm_5v0>;
+ ldo1-in-supply =<&evm_5v0>;
+
+ lp8733_regulators: regulators {
+ lp8733_buck0_reg: buck0 {
+ /* FB_B0 -> LP8733-BUCK1 - VPO_S1_AVS - VDD_CORE_AVS (core, mpu, gpu) */
+ regulator-name = "lp8733-buck0";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ lp8733_buck1_reg: buck1 {
+ /* FB_B1 -> LP8733-BUCK2 - VPO_S2_AVS - VDD_DSP_AVS (DSP/eve/iva) */
+ regulator-name = "lp8733-buck1";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ lp8733_ldo0_reg: ldo0 {
+ /* LDO0 -> LP8733-LDO1 - VPO_L1_3V3 - VDDSHV8 (optional) */
+ regulator-name = "lp8733-ldo0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ lp8733_ldo1_reg: ldo1 {
+ /* LDO1 -> LP8733-LDO2 - VPO_L2_3V3 - VDDA_USB3V3 */
+ regulator-name = "lp8733-ldo1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ lp8732: lp8732@61 {
+ compatible = "ti,lp8732";
+ reg = <0x61>;
+
+ buck0-in-supply =<&vsys_3v3>;
+ buck1-in-supply =<&vsys_3v3>;
+ ldo0-in-supply =<&vsys_3v3>;
+ ldo1-in-supply =<&vsys_3v3>;
+
+ lp8732_regulators: regulators {
+ lp8732_buck0_reg: buck0 {
+ /* FB_B0 -> LP8732-BUCK1 - VPO_S3_1V8 - VDDS_1V8 */
+ regulator-name = "lp8732-buck0";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ lp8732_buck1_reg: buck1 {
+ /* FB_B1 -> LP8732-BUCK2 - VPO_S4_DDR - VDD_DDR_1V35 */
+ regulator-name = "lp8732-buck1";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ lp8732_ldo0_reg: ldo0 {
+ /* LDO0 -> LP8732-LDO1 - VPO_L3_1V8 - VDA_1V8_PLL */
+ regulator-name = "lp8732-ldo0";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ lp8732_ldo1_reg: ldo1 {
+ /* LDO1 -> LP8732-LDO2 - VPO_L4_1V8 - VDA_1V8_PHY */
+ regulator-name = "lp8732-ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&pcf_gpio_21 {
+ interrupt-parent = <&gpio7>;
+ interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+};
+
+&pcf_hdmi {
+ p0 {
+ /*
+ * PM_OEn to High: Disable routing I2C3 to PM_I2C
+ * With this PM_SEL(p3) should not matter
+ */
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "pm_oe_n";
+ };
+};
+
+&mmc1 {
+ vmmc_aux-supply = <&vpo_sd_1v8_3v3>;
+};
+
+&mac {
+ mode-gpios = <&pcf_gpio_21 4 GPIO_ACTIVE_LOW>,
+ <&pcf_hdmi 9 GPIO_ACTIVE_LOW>, /* P11 */
+ <&pcf_hdmi 10 GPIO_ACTIVE_LOW>; /* P12 */
+ dual_emac;
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <2>;
+ phy-mode = "rgmii-id";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <3>;
+ phy-mode = "rgmii-id";
+ dual_emac_res_vlan = <2>;
+};
+
+&davinci_mdio {
+ dp83867_0: ethernet-phy@2 {
+ reg = <2>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ ti,impedance-control = <0x1f>;
+ };
+
+ dp83867_1: ethernet-phy@3 {
+ reg = <3>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ ti,impedance-control = <0x1f>;
+ };
+};
+
+/* No Sata on this device */
+&sata_phy {
+ status = "disabled";
+};
+
+&sata {
+ status = "disabled";
+};
+
+/* No RTC on this device */
+&rtc {
+ status = "disabled";
+};
+
+&usb2_phy1 {
+ phy-supply = <&lp8733_ldo1_reg>;
+};
+
+&usb2_phy2 {
+ phy-supply = <&lp8733_ldo1_reg>;
+};
+
+&dss {
+ /* Supplied by VDA_1V8_PLL */
+ vdda_video-supply = <&lp8732_ldo0_reg>;
+};
+
+&hdmi {
+ /* Supplied by VDA_1V8_PHY */
+ vdda_video-supply = <&lp8732_ldo1_reg>;
+};
diff --git a/arch/arm/boot/dts/dra72-evm-common.dtsi b/arch/arm/boot/dts/dra72-evm-common.dtsi
index c94d8d64710d..e50fbeea96e0 100644
--- a/arch/arm/boot/dts/dra72-evm-common.dtsi
+++ b/arch/arm/boot/dts/dra72-evm-common.dtsi
@@ -18,11 +18,49 @@
display0 = &hdmi0;
};
+ evm_12v0: fixedregulator-evm12v0 {
+ /* main supply */
+ compatible = "regulator-fixed";
+ regulator-name = "evm_12v0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ evm_5v0: fixedregulator-evm5v0 {
+ /* Output 1 of TPS43351QDAPRQ1 on dra72-evm */
+ /* Output 1 of LM5140QRWGTQ1 on dra71-evm */
+ compatible = "regulator-fixed";
+ regulator-name = "evm_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&evm_12v0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vsys_3v3: fixedregulator-vsys3v3 {
+ /* Output 2 of TPS43351QDAPRQ1 on dra72-evm */
+ /* Output 2 of LM5140QRWGTQ1 on dra71-evm */
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&evm_12v0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
evm_3v3_sw: fixedregulator-evm_3v3 {
+ /* TPS22965DSG */
compatible = "regulator-fixed";
regulator-name = "evm_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
+ vin-supply = <&vsys_3v3>;
+ regulator-always-on;
+ regulator-boot-on;
};
aic_dvdd: fixedregulator-aic_dvdd {
@@ -39,6 +77,7 @@
regulator-name = "evm_3v3_sd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
+ vin-supply = <&evm_3v3_sw>;
enable-active-high;
gpio = <&pcf_gpio_21 5 GPIO_ACTIVE_HIGH>;
};
@@ -69,9 +108,6 @@
tpd12s015: encoder {
compatible = "ti,tpd12s015";
- pinctrl-names = "default";
- pinctrl-0 = <&tpd12s015_pins>;
-
gpios = <&pcf_hdmi 4 GPIO_ACTIVE_HIGH>, /* P4, CT CP HPD */
<&pcf_hdmi 5 GPIO_ACTIVE_HIGH>, /* P5, LS OE */
<&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */
@@ -134,72 +170,6 @@
};
&dra7_pmx_core {
- i2c1_pins: pinmux_i2c1_pins {
- pinctrl-single,pins = <
- 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 = <
- 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 = <
- 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 = <
- 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 = <
- DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
- >;
- };
-
- usb2_pins: pinmux_usb2_pins {
- pinctrl-single,pins = <
- DRA7XX_CORE_IOPAD(0x3684, PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
- >;
- };
-
- tps65917_pins_default: tps65917_pins_default {
- pinctrl-single,pins = <
- DRA7XX_CORE_IOPAD(0x3824, PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
- >;
- };
-
mmc1_pins_default: mmc1_pins_default {
pinctrl-single,pins = <
DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */
@@ -240,161 +210,12 @@
DRA7XX_CORE_IOPAD(0x3818, MUX_MODE15 | PULL_UP) /* wakeup0.off */
>;
};
-
- 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 */
- >;
- };
-
- tpd12s015_pins: pinmux_tpd12s015_pins {
- pinctrl-single,pins = <
- DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
- >;
- };
-
- atl_pins: pinmux_atl_pins {
- pinctrl-single,pins = <
- 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 = <
- 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 = <
- 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)
- >;
- };
};
&i2c1 {
status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_pins>;
clock-frequency = <400000>;
- tps65917: tps65917@58 {
- compatible = "ti,tps65917";
- reg = <0x58>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&tps65917_pins_default>;
-
- interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
- interrupt-controller;
- #interrupt-cells = <2>;
-
- ti,system-power-controller;
-
- tps65917_pmic {
- compatible = "ti,tps65917-pmic";
-
- tps65917_regulators: regulators {
- smps1_reg: smps1 {
- /* VDD_MPU */
- regulator-name = "smps1";
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <1250000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- smps2_reg: smps2 {
- /* VDD_CORE */
- regulator-name = "smps2";
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <1150000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- smps3_reg: smps3 {
- /* VDD_GPU IVA DSPEVE */
- regulator-name = "smps3";
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <1250000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- smps4_reg: smps4 {
- /* VDDS1V8 */
- regulator-name = "smps4";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- smps5_reg: smps5 {
- /* VDD_DDR */
- regulator-name = "smps5";
- regulator-min-microvolt = <1350000>;
- regulator-max-microvolt = <1350000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- ldo1_reg: ldo1 {
- /* LDO1_OUT --> SDIO */
- regulator-name = "ldo1";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- regulator-boot-on;
- regulator-allow-bypass;
- };
-
- ldo3_reg: ldo3 {
- /* VDDA_1V8_PHY */
- regulator-name = "ldo3";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- ldo5_reg: ldo5 {
- /* VDDA_1V8_PLL */
- regulator-name = "ldo5";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- ldo4_reg: ldo4 {
- /* VDDA_3V_USB: VDDA_USBHS33 */
- regulator-name = "ldo4";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-boot-on;
- };
- };
- };
-
- tps65917_power_button {
- compatible = "ti,palmas-pwrbutton";
- interrupt-parent = <&tps65917>;
- interrupts = <1 IRQ_TYPE_NONE>;
- wakeup-source;
- ti,palmas-long-press-seconds = <6>;
- };
- };
-
pcf_gpio_21: gpio@21 {
compatible = "ti,pcf8575", "nxp,pcf8575";
reg = <0x21>;
@@ -423,8 +244,6 @@
&i2c5 {
status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c5_pins>;
clock-frequency = <400000>;
pcf_hdmi: pcf8575@26 {
@@ -462,8 +281,6 @@
&gpmc {
status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&nand_default>;
ranges = <0 0 0x08000000 0x01000000>; /* minimum GPMC partition = 16MB */
nand@0,0 {
/* To use NAND, DIP switch SW5 must be set like so:
@@ -548,14 +365,6 @@
};
};
-&usb2_phy1 {
- phy-supply = <&ldo4_reg>;
-};
-
-&usb2_phy2 {
- phy-supply = <&ldo4_reg>;
-};
-
&omap_dwc3_1 {
extcon = <&extcon_usb1>;
};
@@ -566,14 +375,10 @@
&usb1 {
dr_mode = "peripheral";
- pinctrl-names = "default";
- pinctrl-0 = <&usb1_pins>;
};
&usb2 {
dr_mode = "host";
- pinctrl-names = "default";
- pinctrl-0 = <&usb2_pins>;
};
&mmc1 {
@@ -581,7 +386,6 @@
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins_default>;
vmmc-supply = <&evm_3v3_sd>;
- vmmc_aux-supply = <&ldo1_reg>;
bus-width = <4>;
/*
* SDCD signal is not being used here - using the fact that GPIO mode
@@ -603,71 +407,8 @@
max-frequency = <192000000>;
};
-&dra7_pmx_core {
- cpsw_default: cpsw_default {
- pinctrl-single,pins = <
- /* Slave 2 */
- 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 */
- 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 */
- 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 = <
- DRA7XX_CORE_IOPAD(0x363c, MUX_MODE15)
- DRA7XX_CORE_IOPAD(0x3640, MUX_MODE15)
- >;
- };
-};
-
&mac {
status = "okay";
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&cpsw_default>;
- pinctrl-1 = <&cpsw_sleep>;
-};
-
-&davinci_mdio {
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&davinci_mdio_default>;
- pinctrl-1 = <&davinci_mdio_sleep>;
};
&dcan1 {
@@ -741,16 +482,11 @@
&dss {
status = "ok";
-
- vdda_video-supply = <&ldo5_reg>;
};
&hdmi {
status = "ok";
- pinctrl-names = "default";
- pinctrl-0 = <&hdmi_pins>;
-
port {
hdmi_out: endpoint {
remote-endpoint = <&tpd12s015_in>;
@@ -759,9 +495,6 @@
};
&atl {
- pinctrl-names = "default";
- pinctrl-0 = <&atl_pins>;
-
assigned-clocks = <&abe_dpll_sys_clk_mux>,
<&atl_gfclk_mux>,
<&dpll_abe_ck>,
@@ -780,9 +513,6 @@
&mcasp3 {
#sound-dai-cells = <0>;
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&mcasp3_pins>;
- pinctrl-1 = <&mcasp3_sleep_pins>;
assigned-clocks = <&mcasp3_ahclkx_mux>;
assigned-clock-parents = <&atl_clkin2_ck>;
diff --git a/arch/arm/boot/dts/dra72-evm-revc.dts b/arch/arm/boot/dts/dra72-evm-revc.dts
index 3b23b32e1b30..c3d939c9666c 100644
--- a/arch/arm/boot/dts/dra72-evm-revc.dts
+++ b/arch/arm/boot/dts/dra72-evm-revc.dts
@@ -17,17 +17,22 @@
};
};
-&tps65917_regulators {
- ldo2_reg: ldo2 {
- /* LDO2_OUT --> VDDA_1V8_PHY2 */
- regulator-name = "ldo2";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- regulator-boot-on;
+&i2c1 {
+ tps65917: tps65917@58 {
+ reg = <0x58>;
+
+ interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
};
};
+#include "dra72-evm-tps65917.dtsi"
+
+&ldo2_reg {
+ /* LDO2_OUT --> VDDA_1V8_PHY2 */
+ regulator-always-on;
+ regulator-boot-on;
+};
+
&hdmi {
vdda-supply = <&ldo2_reg>;
};
diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
new file mode 100644
index 000000000000..ee6dac44edf1
--- /dev/null
+++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 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/tps65917-q1.pdf
+ */
+
+&tps65917 {
+ compatible = "ti,tps65917";
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ ti,system-power-controller;
+
+ tps65917_pmic {
+ compatible = "ti,tps65917-pmic";
+
+ smps1-in-supply = <&vsys_3v3>;
+ smps2-in-supply = <&vsys_3v3>;
+ smps3-in-supply = <&vsys_3v3>;
+ smps4-in-supply = <&vsys_3v3>;
+ smps5-in-supply = <&vsys_3v3>;
+ ldo1-in-supply = <&vsys_3v3>;
+ ldo2-in-supply = <&vsys_3v3>;
+ ldo3-in-supply = <&vsys_3v3>;
+ ldo4-in-supply = <&evm_5v0>;
+ ldo5-in-supply = <&vsys_3v3>;
+
+ tps65917_regulators: regulators {
+ smps1_reg: smps1 {
+ /* VDD_MPU */
+ regulator-name = "smps1";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps2_reg: smps2 {
+ /* VDD_CORE */
+ regulator-name = "smps2";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ smps3_reg: smps3 {
+ /* VDD_GPU IVA DSPEVE */
+ regulator-name = "smps3";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ smps4_reg: smps4 {
+ /* VDDS1V8 */
+ regulator-name = "smps4";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps5_reg: smps5 {
+ /* VDD_DDR */
+ regulator-name = "smps5";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: ldo1 {
+ /* LDO1_OUT --> SDIO */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1800000>;
+ 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 = <1800000>;
+ regulator-allow-bypass;
+ };
+
+ ldo3_reg: ldo3 {
+ /* VDDA_1V8_PHY */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: ldo5 {
+ /* VDDA_1V8_PLL */
+ regulator-name = "ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo4_reg: ldo4 {
+ /* VDDA_3V_USB: VDDA_USBHS33 */
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+ };
+ };
+
+ tps65917_power_button {
+ compatible = "ti,palmas-pwrbutton";
+ interrupt-parent = <&tps65917>;
+ interrupts = <1 IRQ_TYPE_NONE>;
+ wakeup-source;
+ ti,palmas-long-press-seconds = <6>;
+ };
+};
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index e3a9b6985693..cd9c4ff12654 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -15,16 +15,16 @@
};
};
-&tps65917_regulators {
- ldo2_reg: ldo2 {
- /* LDO2_OUT --> TP1017 (UNUSED) */
- regulator-name = "ldo2";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-allow-bypass;
+&i2c1 {
+ tps65917: tps65917@58 {
+ reg = <0x58>;
+
+ interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
};
};
+#include "dra72-evm-tps65917.dtsi"
+
&hdmi {
vdda-supply = <&ldo3_reg>;
};
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
index cd119400f440..0124faf175c8 100644
--- a/arch/arm/boot/dts/emev2.dtsi
+++ b/arch/arm/boot/dts/emev2.dtsi
@@ -8,13 +8,14 @@
* kind, whether express or implied.
*/
-#include "skeleton.dtsi"
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
compatible = "renesas,emev2";
interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
aliases {
gpio0 = &gpio0;
diff --git a/arch/arm/boot/dts/exynos3250-artik5-eval.dts b/arch/arm/boot/dts/exynos3250-artik5-eval.dts
index be4d6aa379f3..4bd2ee87124e 100644
--- a/arch/arm/boot/dts/exynos3250-artik5-eval.dts
+++ b/arch/arm/boot/dts/exynos3250-artik5-eval.dts
@@ -28,7 +28,7 @@
vqmmc-supply = <&ldo3_reg>;
card-detect-delay = <200>;
clock-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ max-frequency = <100000000>;
samsung,dw-mshc-ciu-div = <1>;
samsung,dw-mshc-sdr-timing = <0 1>;
samsung,dw-mshc-ddr-timing = <1 2>;
diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi
index a70819b1b739..59c89d7662a8 100644
--- a/arch/arm/boot/dts/exynos3250-artik5.dtsi
+++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi
@@ -310,7 +310,7 @@
card-detect-delay = <200>;
vmmc-supply = <&ldo12_reg>;
clock-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ max-frequency = <100000000>;
samsung,dw-mshc-ciu-div = <1>;
samsung,dw-mshc-sdr-timing = <0 1>;
samsung,dw-mshc-ddr-timing = <1 2>;
diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 66f04f6ba6bb..cccfe4b791d1 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -435,7 +435,7 @@
card-detect-delay = <200>;
vmmc-supply = <&vemmc_reg>;
clock-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ max-frequency = <100000000>;
samsung,dw-mshc-ciu-div = <1>;
samsung,dw-mshc-sdr-timing = <0 1>;
samsung,dw-mshc-ddr-timing = <1 2>;
diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index ec331169c3d9..a149f148e659 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -362,8 +362,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
- interrupts = <0 32 0>, <0 33 0>, <0 34 0>, <0 35 0>,
- <0 36 0>, <0 37 0>, <0 38 0>, <0 39 0>;
+ 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 36 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
};
@@ -373,8 +379,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
- interrupts = <0 40 0>, <0 41 0>, <0 42 0>, <0 43 0>,
- <0 44 0>, <0 45 0>, <0 46 0>, <0 47 0>;
+ interrupts = <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>;
#interrupt-cells = <2>;
};
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 3967ee5f7752..548413e23c47 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -649,7 +649,7 @@
card-detect-delay = <200>;
vmmc-supply = <&ldo12_reg>;
clock-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ max-frequency = <100000000>;
samsung,dw-mshc-ciu-div = <1>;
samsung,dw-mshc-sdr-timing = <0 1>;
samsung,dw-mshc-ddr-timing = <1 2>;
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index e9d2556c0dfd..ba17ee1eb749 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -20,6 +20,8 @@
#include "exynos4-cpu-thermal.dtsi"
#include "exynos-syscon-restart.dtsi"
#include <dt-bindings/clock/exynos3250.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
compatible = "samsung,exynos3250";
@@ -211,7 +213,8 @@
rtc: rtc@10070000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
- interrupts = <0 73 0>, <0 74 0>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&pmu_system_controller>;
status = "disabled";
};
@@ -219,7 +222,7 @@
tmu: tmu@100C0000 {
compatible = "samsung,exynos3250-tmu";
reg = <0x100C0000 0x100>;
- interrupts = <0 216 0>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_TMU_APBIF>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -234,14 +237,21 @@
<0x10482000 0x1000>,
<0x10484000 0x2000>,
<0x10486000 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
mct@10050000 {
compatible = "samsung,exynos4210-mct";
reg = <0x10050000 0x800>;
- interrupts = <0 218 0>, <0 219 0>, <0 220 0>, <0 221 0>,
- <0 223 0>, <0 226 0>, <0 227 0>, <0 228 0>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_FIN_PLL>, <&cmu CLK_MCT>;
clock-names = "fin_pll", "mct";
};
@@ -249,24 +259,24 @@
pinctrl_1: pinctrl@11000000 {
compatible = "samsung,exynos3250-pinctrl";
reg = <0x11000000 0x1000>;
- interrupts = <0 225 0>;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
- interrupts = <0 48 0>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
};
};
pinctrl_0: pinctrl@11400000 {
compatible = "samsung,exynos3250-pinctrl";
reg = <0x11400000 0x1000>;
- interrupts = <0 240 0>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
};
jpeg: codec@11830000 {
compatible = "samsung,exynos3250-jpeg";
reg = <0x11830000 0x1000>;
- interrupts = <0 171 0>;
+ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_JPEG>, <&cmu CLK_SCLK_JPEG>;
clock-names = "jpeg", "sclk";
power-domains = <&pd_cam>;
@@ -280,7 +290,8 @@
sysmmu_jpeg: sysmmu@11A60000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x11a60000 0x1000>;
- interrupts = <0 156 0>, <0 161 0>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "sysmmu", "master";
clocks = <&cmu CLK_SMMUJPEG>, <&cmu CLK_JPEG>;
power-domains = <&pd_cam>;
@@ -291,7 +302,9 @@
compatible = "samsung,exynos3250-fimd";
reg = <0x11c00000 0x30000>;
interrupt-names = "fifo", "vsync", "lcd_sys";
- interrupts = <0 84 0>, <0 85 0>, <0 86 0>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
clock-names = "sclk_fimd", "fimd";
power-domains = <&pd_lcd0>;
@@ -303,7 +316,7 @@
dsi_0: dsi@11C80000 {
compatible = "samsung,exynos3250-mipi-dsi";
reg = <0x11C80000 0x10000>;
- interrupts = <0 83 0>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
samsung,phy-type = <0>;
power-domains = <&pd_lcd0>;
phys = <&mipi_phy 1>;
@@ -318,7 +331,8 @@
sysmmu_fimd0: sysmmu@11E20000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x11e20000 0x1000>;
- interrupts = <0 80 0>, <0 81 0>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "sysmmu", "master";
clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
power-domains = <&pd_lcd0>;
@@ -328,7 +342,7 @@
hsotg: hsotg@12480000 {
compatible = "snps,dwc2";
reg = <0x12480000 0x20000>;
- interrupts = <0 141 0>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_USBOTG>;
clock-names = "otg";
phys = <&exynos_usbphy 0>;
@@ -339,7 +353,7 @@
mshc_0: mshc@12510000 {
compatible = "samsung,exynos5420-dw-mshc";
reg = <0x12510000 0x1000>;
- interrupts = <0 142 0>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_SDMMC0>, <&cmu CLK_SCLK_MMC0>;
clock-names = "biu", "ciu";
fifo-depth = <0x80>;
@@ -351,7 +365,7 @@
mshc_1: mshc@12520000 {
compatible = "samsung,exynos5420-dw-mshc";
reg = <0x12520000 0x1000>;
- interrupts = <0 143 0>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_SDMMC1>, <&cmu CLK_SCLK_MMC1>;
clock-names = "biu", "ciu";
fifo-depth = <0x80>;
@@ -363,7 +377,7 @@
mshc_2: mshc@12530000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12530000 0x1000>;
- interrupts = <0 144 0>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_SDMMC2>, <&cmu CLK_SCLK_MMC2>;
clock-names = "biu", "ciu";
fifo-depth = <0x80>;
@@ -391,7 +405,7 @@
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
- interrupts = <0 138 0>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -402,7 +416,7 @@
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
- interrupts = <0 139 0>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -415,7 +429,7 @@
compatible = "samsung,exynos3250-adc",
"samsung,exynos-adc-v2";
reg = <0x126C0000 0x100>;
- interrupts = <0 137 0>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "adc", "sclk";
clocks = <&cmu CLK_TSADC>, <&cmu CLK_SCLK_TSADC>;
#io-channel-cells = <1>;
@@ -427,7 +441,7 @@
mfc: codec@13400000 {
compatible = "samsung,mfc-v7";
reg = <0x13400000 0x10000>;
- interrupts = <0 102 0>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "mfc", "sclk_mfc";
clocks = <&cmu CLK_MFC>, <&cmu CLK_SCLK_MFC>;
power-domains = <&pd_mfc>;
@@ -437,7 +451,8 @@
sysmmu_mfc: sysmmu@13620000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x13620000 0x1000>;
- interrupts = <0 96 0>, <0 98 0>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "sysmmu", "master";
clocks = <&cmu CLK_SMMUMFC_L>, <&cmu CLK_MFC>;
power-domains = <&pd_mfc>;
@@ -447,7 +462,7 @@
serial_0: serial@13800000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13800000 0x100>;
- interrupts = <0 109 0>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
pinctrl-names = "default";
@@ -458,7 +473,7 @@
serial_1: serial@13810000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13810000 0x100>;
- interrupts = <0 110 0>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_UART1>, <&cmu CLK_SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0";
pinctrl-names = "default";
@@ -469,7 +484,7 @@
serial_2: serial@13820000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13820000 0x100>;
- interrupts = <0 111 0>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_UART2>, <&cmu CLK_SCLK_UART2>;
clock-names = "uart", "clk_uart_baud0";
pinctrl-names = "default";
@@ -482,7 +497,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13860000 0x100>;
- interrupts = <0 113 0>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C0>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -495,7 +510,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13870000 0x100>;
- interrupts = <0 114 0>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C1>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -508,7 +523,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13880000 0x100>;
- interrupts = <0 115 0>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C2>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -521,7 +536,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13890000 0x100>;
- interrupts = <0 116 0>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C3>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -534,7 +549,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138A0000 0x100>;
- interrupts = <0 117 0>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C4>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -547,7 +562,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138B0000 0x100>;
- interrupts = <0 118 0>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C5>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -560,7 +575,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138C0000 0x100>;
- interrupts = <0 119 0>;
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C6>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -573,7 +588,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138D0000 0x100>;
- interrupts = <0 120 0>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2C7>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -584,7 +599,7 @@
spi_0: spi@13920000 {
compatible = "samsung,exynos4210-spi";
reg = <0x13920000 0x100>;
- interrupts = <0 121 0>;
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 7>, <&pdma0 6>;
dma-names = "tx", "rx";
#address-cells = <1>;
@@ -600,7 +615,7 @@
spi_1: spi@13930000 {
compatible = "samsung,exynos4210-spi";
reg = <0x13930000 0x100>;
- interrupts = <0 122 0>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma1 7>, <&pdma1 6>;
dma-names = "tx", "rx";
#address-cells = <1>;
@@ -616,7 +631,7 @@
i2s2: i2s@13970000 {
compatible = "samsung,s3c6410-i2s";
reg = <0x13970000 0x100>;
- interrupts = <0 126 0>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_I2S>, <&cmu CLK_SCLK_I2S>;
clock-names = "iis", "i2s_opclk0";
dmas = <&pdma0 14>, <&pdma0 13>;
@@ -629,15 +644,19 @@
pwm: pwm@139D0000 {
compatible = "samsung,exynos4210-pwm";
reg = <0x139D0000 0x1000>;
- interrupts = <0 104 0>, <0 105 0>, <0 106 0>,
- <0 107 0>, <0 108 0>;
+ 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>;
#pwm-cells = <3>;
status = "disabled";
};
pmu {
compatible = "arm,cortex-a7-pmu";
- interrupts = <0 18 0>, <0 19 0>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
};
ppmu_dmc0: ppmu_dmc0@106a0000 {
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 5f034eb5a5e2..c64737baa45e 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -21,6 +21,8 @@
#include <dt-bindings/clock/exynos4.h>
#include <dt-bindings/clock/exynos-audss-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
#include "exynos-syscon-restart.dtsi"
/ {
@@ -78,6 +80,11 @@
reg = <0x10000000 0x100>;
};
+ scu: snoop-control-unit@10500000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x10500000 0x2000>;
+ };
+
memory-controller@12570000 {
compatible = "samsung,exynos4210-srom";
reg = <0x12570000 0x14>;
@@ -168,7 +175,7 @@
dsi_0: dsi@11C80000 {
compatible = "samsung,exynos4210-mipi-dsi";
reg = <0x11C80000 0x10000>;
- interrupts = <0 79 0>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_lcd0>;
phys = <&mipi_phy 1>;
phy-names = "dsim";
@@ -191,7 +198,7 @@
fimc_0: fimc@11800000 {
compatible = "samsung,exynos4210-fimc";
reg = <0x11800000 0x1000>;
- interrupts = <0 84 0>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_FIMC0>, <&clock CLK_SCLK_FIMC0>;
clock-names = "fimc", "sclk_fimc";
power-domains = <&pd_cam>;
@@ -203,7 +210,7 @@
fimc_1: fimc@11810000 {
compatible = "samsung,exynos4210-fimc";
reg = <0x11810000 0x1000>;
- interrupts = <0 85 0>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_FIMC1>, <&clock CLK_SCLK_FIMC1>;
clock-names = "fimc", "sclk_fimc";
power-domains = <&pd_cam>;
@@ -215,7 +222,7 @@
fimc_2: fimc@11820000 {
compatible = "samsung,exynos4210-fimc";
reg = <0x11820000 0x1000>;
- interrupts = <0 86 0>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_FIMC2>, <&clock CLK_SCLK_FIMC2>;
clock-names = "fimc", "sclk_fimc";
power-domains = <&pd_cam>;
@@ -227,7 +234,7 @@
fimc_3: fimc@11830000 {
compatible = "samsung,exynos4210-fimc";
reg = <0x11830000 0x1000>;
- interrupts = <0 87 0>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_FIMC3>, <&clock CLK_SCLK_FIMC3>;
clock-names = "fimc", "sclk_fimc";
power-domains = <&pd_cam>;
@@ -239,7 +246,7 @@
csis_0: csis@11880000 {
compatible = "samsung,exynos4210-csis";
reg = <0x11880000 0x4000>;
- interrupts = <0 78 0>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_CSIS0>, <&clock CLK_SCLK_CSIS0>;
clock-names = "csis", "sclk_csis";
bus-width = <4>;
@@ -254,7 +261,7 @@
csis_1: csis@11890000 {
compatible = "samsung,exynos4210-csis";
reg = <0x11890000 0x4000>;
- interrupts = <0 80 0>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_CSIS1>, <&clock CLK_SCLK_CSIS1>;
clock-names = "csis", "sclk_csis";
bus-width = <2>;
@@ -270,7 +277,7 @@
watchdog: watchdog@10060000 {
compatible = "samsung,s3c2410-wdt";
reg = <0x10060000 0x100>;
- interrupts = <0 43 0>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_WDT>;
clock-names = "watchdog";
status = "disabled";
@@ -280,7 +287,8 @@
compatible = "samsung,s3c6410-rtc";
reg = <0x10070000 0x100>;
interrupt-parent = <&pmu_system_controller>;
- interrupts = <0 44 0>, <0 45 0>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_RTC>;
clock-names = "rtc";
status = "disabled";
@@ -289,7 +297,7 @@
keypad: keypad@100A0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
- interrupts = <0 109 0>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_KEYIF>;
clock-names = "keypad";
status = "disabled";
@@ -298,7 +306,7 @@
sdhci_0: sdhci@12510000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12510000 0x100>;
- interrupts = <0 73 0>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
@@ -307,7 +315,7 @@
sdhci_1: sdhci@12520000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12520000 0x100>;
- interrupts = <0 74 0>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
@@ -316,7 +324,7 @@
sdhci_2: sdhci@12530000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12530000 0x100>;
- interrupts = <0 75 0>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
@@ -325,7 +333,7 @@
sdhci_3: sdhci@12540000 {
compatible = "samsung,exynos4210-sdhci";
reg = <0x12540000 0x100>;
- interrupts = <0 76 0>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
clock-names = "hsmmc", "mmc_busclk.2";
status = "disabled";
@@ -344,7 +352,7 @@
hsotg: hsotg@12480000 {
compatible = "samsung,s3c6400-hsotg";
reg = <0x12480000 0x20000>;
- interrupts = <0 71 0>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB_DEVICE>;
clock-names = "otg";
phys = <&exynos_usbphy 0>;
@@ -355,7 +363,7 @@
ehci: ehci@12580000 {
compatible = "samsung,exynos4210-ehci";
reg = <0x12580000 0x100>;
- interrupts = <0 70 0>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB_HOST>;
clock-names = "usbhost";
status = "disabled";
@@ -381,7 +389,7 @@
ohci: ohci@12590000 {
compatible = "samsung,exynos4210-ohci";
reg = <0x12590000 0x100>;
- interrupts = <0 70 0>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB_HOST>;
clock-names = "usbhost";
status = "disabled";
@@ -423,7 +431,7 @@
mfc: codec@13400000 {
compatible = "samsung,mfc-v5";
reg = <0x13400000 0x10000>;
- interrupts = <0 94 0>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_mfc>;
clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
clock-names = "mfc", "sclk_mfc";
@@ -434,7 +442,7 @@
serial_0: serial@13800000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13800000 0x100>;
- interrupts = <0 52 0>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
dmas = <&pdma0 15>, <&pdma0 16>;
@@ -445,7 +453,7 @@
serial_1: serial@13810000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13810000 0x100>;
- interrupts = <0 53 0>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0";
dmas = <&pdma1 15>, <&pdma1 16>;
@@ -456,7 +464,7 @@
serial_2: serial@13820000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13820000 0x100>;
- interrupts = <0 54 0>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
clock-names = "uart", "clk_uart_baud0";
dmas = <&pdma0 17>, <&pdma0 18>;
@@ -467,7 +475,7 @@
serial_3: serial@13830000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13830000 0x100>;
- interrupts = <0 55 0>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
clock-names = "uart", "clk_uart_baud0";
dmas = <&pdma1 17>, <&pdma1 18>;
@@ -480,7 +488,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13860000 0x100>;
- interrupts = <0 58 0>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C0>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -493,7 +501,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13870000 0x100>;
- interrupts = <0 59 0>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C1>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -506,7 +514,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13880000 0x100>;
- interrupts = <0 60 0>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C2>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -519,7 +527,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x13890000 0x100>;
- interrupts = <0 61 0>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C3>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -532,7 +540,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138A0000 0x100>;
- interrupts = <0 62 0>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C4>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -545,7 +553,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138B0000 0x100>;
- interrupts = <0 63 0>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C5>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -558,7 +566,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138C0000 0x100>;
- interrupts = <0 64 0>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C6>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -571,7 +579,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-i2c";
reg = <0x138D0000 0x100>;
- interrupts = <0 65 0>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C7>;
clock-names = "i2c";
pinctrl-names = "default";
@@ -584,7 +592,7 @@
#size-cells = <0>;
compatible = "samsung,s3c2440-hdmiphy-i2c";
reg = <0x138E0000 0x100>;
- interrupts = <0 93 0>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_I2C_HDMI>;
clock-names = "i2c";
status = "disabled";
@@ -598,7 +606,7 @@
spi_0: spi@13920000 {
compatible = "samsung,exynos4210-spi";
reg = <0x13920000 0x100>;
- interrupts = <0 66 0>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 7>, <&pdma0 6>;
dma-names = "tx", "rx";
#address-cells = <1>;
@@ -613,7 +621,7 @@
spi_1: spi@13930000 {
compatible = "samsung,exynos4210-spi";
reg = <0x13930000 0x100>;
- interrupts = <0 67 0>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma1 7>, <&pdma1 6>;
dma-names = "tx", "rx";
#address-cells = <1>;
@@ -628,7 +636,7 @@
spi_2: spi@13940000 {
compatible = "samsung,exynos4210-spi";
reg = <0x13940000 0x100>;
- interrupts = <0 68 0>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 9>, <&pdma0 8>;
dma-names = "tx", "rx";
#address-cells = <1>;
@@ -643,7 +651,11 @@
pwm: pwm@139D0000 {
compatible = "samsung,exynos4210-pwm";
reg = <0x139D0000 0x1000>;
- interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PWM>;
clock-names = "timers";
#pwm-cells = <3>;
@@ -660,7 +672,7 @@
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
- interrupts = <0 35 0>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -671,7 +683,7 @@
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
- interrupts = <0 36 0>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -682,7 +694,7 @@
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
- interrupts = <0 34 0>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -712,7 +724,7 @@
jpeg_codec: jpeg-codec@11840000 {
compatible = "samsung,exynos4210-jpeg";
reg = <0x11840000 0x1000>;
- interrupts = <0 88 0>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_JPEG>;
clock-names = "jpeg";
power-domains = <&pd_cam>;
@@ -722,7 +734,7 @@
rotator: rotator@12810000 {
compatible = "samsung,exynos4210-rotator";
reg = <0x12810000 0x64>;
- interrupts = <0 83 0>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_ROTATOR>;
clock-names = "rotator";
iommus = <&sysmmu_rotator>;
@@ -731,7 +743,7 @@
hdmi: hdmi@12D00000 {
compatible = "samsung,exynos4210-hdmi";
reg = <0x12D00000 0x70000>;
- interrupts = <0 92 0>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy",
"mout_hdmi";
clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
@@ -746,7 +758,7 @@
hdmicec: cec@100B0000 {
compatible = "samsung,s5p-cec";
reg = <0x100B0000 0x200>;
- interrupts = <0 114 0>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_HDMI_CEC>;
clock-names = "hdmicec";
samsung,syscon-phandle = <&pmu_system_controller>;
@@ -757,7 +769,7 @@
mixer: mixer@12C10000 {
compatible = "samsung,exynos4210-mixer";
- interrupts = <0 91 0>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
power-domains = <&pd_tv>;
iommus = <&sysmmu_tv>;
@@ -984,7 +996,7 @@
sss: sss@10830000 {
compatible = "samsung,exynos4210-secss";
reg = <0x10830000 0x300>;
- interrupts = <0 112 0>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SSS>;
clock-names = "secss";
};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index d9b6d25e4abe..f280954b260a 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -537,8 +537,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
- interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
- <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
};
@@ -548,8 +554,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
- interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
- <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 2d9b02967105..7f3a18c8f60f 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -109,12 +109,12 @@
#interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
- interrupt-map = <0 &gic 0 57 0>,
- <1 &gic 0 69 0>,
+ interrupt-map = <0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
+ <1 &gic 0 69 IRQ_TYPE_LEVEL_HIGH>,
<2 &combiner 12 6>,
<3 &combiner 12 7>,
- <4 &gic 0 42 0>,
- <5 &gic 0 48 0>;
+ <4 &gic 0 42 IRQ_TYPE_LEVEL_HIGH>,
+ <5 &gic 0 48 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -127,18 +127,18 @@
pinctrl_0: pinctrl@11400000 {
compatible = "samsung,exynos4210-pinctrl";
reg = <0x11400000 0x1000>;
- interrupts = <0 47 0>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_1: pinctrl@11000000 {
compatible = "samsung,exynos4210-pinctrl";
reg = <0x11000000 0x1000>;
- interrupts = <0 46 0>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
wakup_eint: wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -182,7 +182,7 @@
g2d: g2d@12800000 {
compatible = "samsung,s5pv210-g2d";
reg = <0x12800000 0x1000>;
- interrupts = <0 89 0>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
clock-names = "sclk_fimg2d", "fimg2d";
power-domains = <&pd_lcd0>;
@@ -424,10 +424,22 @@
&combiner {
samsung,combiner-nr = <16>;
- interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
- <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
- <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
- <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
};
&mdma1 {
diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts
new file mode 100644
index 000000000000..76d87f397178
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -0,0 +1,240 @@
+/*
+ * TOPEET's Exynos4412 based itop board device tree source
+ *
+ * Copyright (c) 2016 SUMOMO Computer Association
+ * https://www.sumomo.mobi
+ * Randy Li <ayaka@soulik.info>
+ *
+ * Device tree source file for TOPEET iTop Exynos 4412 core board
+ * which is based on Samsung's Exynos4412 SoC.
+ *
+ * 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/pwm/pwm.h>
+#include <dt-bindings/sound/samsung-i2s.h>
+#include "exynos4412-itop-scp-core.dtsi"
+
+/ {
+ model = "TOPEET iTop 4412 Elite board based on Exynos4412";
+ compatible = "topeet,itop4412-elite", "samsung,exynos4412", "samsung,exynos4";
+
+ chosen {
+ bootargs = "root=/dev/mmcblk0p2 rw rootfstype=ext4 rootdelay=1 rootwait";
+ stdout-path = "serial2:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led2 {
+ label = "red:system";
+ gpios = <&gpx1 0 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led3 {
+ label = "red:user";
+ gpios = <&gpk1 1 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ home {
+ label = "GPIO Key Home";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpx1 1 GPIO_ACTIVE_LOW>;
+ };
+
+ back {
+ label = "GPIO Key Back";
+ linux,code = <KEY_BACK>;
+ gpios = <&gpx1 2 GPIO_ACTIVE_LOW>;
+ };
+
+ sleep {
+ label = "GPIO Key Sleep";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpx3 3 GPIO_ACTIVE_LOW>;
+ };
+
+ vol-up {
+ label = "GPIO Key Vol+";
+ linux,code = <KEY_UP>;
+ gpios = <&gpx2 1 GPIO_ACTIVE_LOW>;
+ };
+
+ vol-down {
+ label = "GPIO Key Vol-";
+ linux,code = <KEY_DOWN>;
+ gpios = <&gpx2 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "wm-sound";
+
+ assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>,
+ <&clock_audss EXYNOS_MOUT_I2S>,
+ <&clock_audss EXYNOS_DOUT_SRP>,
+ <&clock_audss EXYNOS_DOUT_AUD_BUS>;
+ assigned-clock-parents = <&clock CLK_FOUT_EPLL>,
+ <&clock_audss EXYNOS_MOUT_AUDSS>;
+ assigned-clock-rates = <0>,
+ <0>,
+ <112896000>,
+ <11289600>;
+
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Line", "Line In",
+ "Line", "Line Out",
+ "Speaker", "Speaker",
+ "Headphone", "Headphone Jack";
+ simple-audio-card,routing =
+ "Headphone Jack", "HP_L",
+ "Headphone Jack", "HP_R",
+ "Speaker", "SPK_LP",
+ "Speaker", "SPK_LN",
+ "Speaker", "SPK_RP",
+ "Speaker", "SPK_RN",
+ "LINPUT1", "Mic Jack",
+ "LINPUT3", "Mic Jack",
+ "RINPUT1", "Mic Jack",
+ "RINPUT2", "Mic Jack";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0 0>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&codec>;
+ clocks = <&i2s0 CLK_I2S_CDCLK>;
+ system-clock-frequency = <11289600>;
+ };
+ };
+
+ beep {
+ compatible = "pwm-beeper";
+ pwms = <&pwm 0 4000000 PWM_POLARITY_INVERTED>;
+ };
+
+ camera: camera {
+ pinctrl-0 = <&cam_port_a_clk_active>;
+ pinctrl-names = "default";
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_CAM0>;
+ assigned-clock-parents = <&clock CLK_XUSBXTI>;
+ };
+};
+
+&adc {
+ vdd-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&ehci {
+ status = "okay";
+ /* In order to reset USB ethernet */
+ samsung,vbus-gpio = <&gpc0 1 GPIO_ACTIVE_HIGH>;
+
+ port@0 {
+ status = "okay";
+ };
+
+ port@2 {
+ status = "okay";
+ };
+};
+
+&exynos_usbphy {
+ status = "okay";
+};
+
+&fimc_0 {
+ status = "okay";
+ assigned-clocks = <&clock CLK_MOUT_FIMC0>,
+ <&clock CLK_SCLK_FIMC0>;
+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-rates = <0>, <176000000>;
+};
+
+&hsotg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&i2c_4 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c4_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ codec: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ clocks = <&pmu_system_controller 0>;
+ clock-names = "MCLK1";
+ wlf,shared-lrclk;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0 {
+ pinctrl-0 = <&i2s0_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+ clocks = <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_DOUT_AUD_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+};
+
+&pinctrl_1 {
+ ether-reset {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+};
+
+&pwm {
+ status = "okay";
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ samsung,pwm-outputs = <0>;
+};
+
+&sdhci_2 {
+ bus-width = <4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+ pinctrl-names = "default";
+ cd-gpio = <&gpx0 7 GPIO_ACTIVE_LOW>;
+ cap-sd-highspeed;
+ vmmc-supply = <&ldo23_reg>;
+ vqmmc-supply = <&ldo17_reg>;
+ status = "okay";
+};
+
+&serial_1 {
+ status = "okay";
+};
+
+&serial_2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
new file mode 100644
index 000000000000..a36cd36a26b8
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
@@ -0,0 +1,501 @@
+/*
+ * TOPEET's Exynos4412 based itop board device tree source
+ *
+ * Copyright (c) 2016 SUMOMO Computer Association
+ * https://www.sumomo.mobi
+ * Randy Li <ayaka@soulik.info>
+ *
+ * Device tree source file for TOPEET iTop Exynos 4412 SCP package core
+ * board which is based on Samsung's Exynos4412 SoC.
+ *
+ * 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/clock/samsung,s2mps11.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "exynos4412.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
+#include "exynos-mfc-reserved-memory.dtsi"
+
+/ {
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x40000000 0x40000000>;
+ };
+
+ firmware@0203F000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x0203F000 0x1000>;
+ };
+
+ fixed-rate-clocks {
+ xxti {
+ compatible = "samsung,clock-xxti";
+ clock-frequency = <0>;
+ };
+
+ xusbxti {
+ compatible = "samsung,clock-xusbxti";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ /* Corresponds to 800MHz at freq_table */
+ cooling-device = <&cpu0 7 7>;
+ };
+ map1 {
+ /* Corresponds to 200MHz at freq_table */
+ cooling-device = <&cpu0 13 13>;
+ };
+ };
+ };
+ };
+
+ usb-hub {
+ compatible = "smsc,usb3503a";
+ reset-gpios = <&gpm2 4 GPIO_ACTIVE_LOW>;
+ connect-gpios = <&gpm3 3 GPIO_ACTIVE_HIGH>;
+ intn-gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsic_reset>;
+ };
+};
+
+&bus_dmc {
+ devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
+ vdd-supply = <&buck1_reg>;
+ status = "okay";
+};
+
+&bus_acp {
+ devfreq = <&bus_dmc>;
+ status = "okay";
+};
+
+&bus_c2c {
+ devfreq = <&bus_dmc>;
+ status = "okay";
+};
+
+&bus_leftbus {
+ devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
+ vdd-supply = <&buck3_reg>;
+ status = "okay";
+};
+
+&bus_rightbus {
+ devfreq = <&bus_leftbus>;
+ status = "okay";
+};
+
+&bus_fsys {
+ devfreq = <&bus_leftbus>;
+ status = "okay";
+};
+
+&bus_peri {
+ devfreq = <&bus_leftbus>;
+ status = "okay";
+};
+
+&bus_mfc {
+ devfreq = <&bus_leftbus>;
+ status = "okay";
+};
+
+&cpu0 {
+ cpu0-supply = <&buck2_reg>;
+};
+
+&hsotg {
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+};
+
+&i2c_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <400000>;
+ pinctrl-0 = <&i2c1_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ s5m8767: s5m8767-pmic@66 {
+ compatible = "samsung,s5m8767-pmic";
+ reg = <0x66>;
+
+ s5m8767,pmic-buck-default-dvs-idx = <3>;
+
+ s5m8767,pmic-buck-dvs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>,
+ <&gpb 6 GPIO_ACTIVE_HIGH>,
+ <&gpb 7 GPIO_ACTIVE_HIGH>;
+
+ s5m8767,pmic-buck-ds-gpios = <&gpm3 5 GPIO_ACTIVE_HIGH>,
+ <&gpm3 6 GPIO_ACTIVE_HIGH>,
+ <&gpm3 7 GPIO_ACTIVE_HIGH>;
+
+ /* VDD_ARM */
+ s5m8767,pmic-buck2-dvs-voltage = <1356250>, <1300000>,
+ <1243750>, <1118750>,
+ <1068750>, <1012500>,
+ <956250>, <900000>;
+ /* VDD_INT */
+ s5m8767,pmic-buck3-dvs-voltage = <1000000>, <1000000>,
+ <925000>, <925000>,
+ <887500>, <887500>,
+ <850000>, <850000>;
+ /* VDD_G3D */
+ s5m8767,pmic-buck4-dvs-voltage = <1081250>, <1081250>,
+ <1025000>, <950000>,
+ <918750>, <900000>,
+ <875000>, <831250>;
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ALIVE";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ /* SCP uses 1.5v, POP uses 1.2v */
+ ldo2_reg: LDO2 {
+ regulator-name = "VDDQ_M12";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDDIOAP_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDDQ_PRE";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VDD_LDO5";
+ op_mode = <0>; /* Always off Mode */
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD10_MPLL";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD10_XPLL";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VDD10_MIPI";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VDD33_LCD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDD18_MIPI";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD18_ABB1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD33_UOTG";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDDIOPERI_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDD18_ABB02";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDD10_USH";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDD18_HSIC";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "VDDIOAP_MMC012_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ /* Used by HSIC */
+ ldo18_reg: LDO18 {
+ regulator-name = "VDDIOPERI_28";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "VDD_LDO19";
+ op_mode = <0>; /* Always off Mode */
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "VDD28_CAM";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "VDD28_AF";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "VDDA28_2M";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "VDD28_TF";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "VDD33_A31";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "VDD18_CAM";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "VDD18_A31";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "GPS_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "DVDD12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1456250>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_m12";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd12_5m";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "pvdd_buck7";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "pvdd_buck8";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ op_mode = <1>; /* Normal Mode */
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vddf28_emmc";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3000000>;
+ op_mode = <1>; /* Normal Mode */
+ };
+ };
+
+ s5m8767_osc: clocks {
+ #clock-cells = <1>;
+ clock-output-names = "s5m8767_ap",
+ "s5m8767_cp", "s5m8767_bt";
+ };
+
+ };
+};
+
+&mfc {
+ status = "okay";
+};
+
+&mshc_0 {
+ pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+ pinctrl-names = "default";
+ status = "okay";
+ vmmc-supply = <&buck9_reg>;
+ num-slots = <1>;
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+&pinctrl_1 {
+ hsic_reset: hsic-reset {
+ samsung,pins = "gpm2-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+ };
+};
+
+&rtc {
+ status = "okay";
+ clocks = <&clock CLK_RTC>, <&s5m8767_osc S2MPS11_CLK_AP>;
+ clock-names = "rtc", "rtc_src";
+};
+
+&tmu {
+ vtmu-supply = <&ldo16_reg>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
index 61906b35ea7a..153a75fe6e24 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -64,6 +64,11 @@
};
};
+&adc {
+ vdd-supply = <&ldo10_reg>;
+ status = "okay";
+};
+
/* VDDQ for MSHC (eMMC card) */
&buck8_reg {
regulator-name = "BUCK8_VDDQ_MMC4_2.8V";
diff --git a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
deleted file mode 100644
index 76cfd872ead3..000000000000
--- a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * Samsung's Exynos4415 SoCs pin-mux and pin-config device tree source
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Samsung's Exynos4415 SoCs pin-mux and pin-config optiosn are listed as device
- * tree nodes are listed in this file.
- *
- * 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/pinctrl/samsung.h>
-
-&pinctrl_0 {
- gpa0: gpa0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpa1: gpa1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpb: gpb {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpc0: gpc0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpc1: gpc1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpd0: gpd0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpd1: gpd1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpf0: gpf0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpf1: gpf1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpf2: gpf2 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- uart0_data: uart0-data {
- samsung,pins = "gpa0-0", "gpa0-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart0_fctl: uart0-fctl {
- samsung,pins = "gpa0-2", "gpa0-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart1_data: uart1-data {
- samsung,pins = "gpa0-4", "gpa0-5";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart1_fctl: uart1-fctl {
- samsung,pins = "gpa0-6", "gpa0-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart2_data: uart2-data {
- samsung,pins = "gpa1-0", "gpa1-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart2_fctl: uart2-fctl {
- samsung,pins = "gpa1-2", "gpa1-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart3_data: uart3-data {
- samsung,pins = "gpa1-4", "gpa1-5";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c2_bus: i2c2-bus {
- samsung,pins = "gpa0-6", "gpa0-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c3_bus: i2c3-bus {
- samsung,pins = "gpa1-2", "gpa1-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- spi0_bus: spi0-bus {
- samsung,pins = "gpb-0", "gpb-2", "gpb-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c4_bus: i2c4-bus {
- samsung,pins = "gpb-0", "gpb-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- spi1_bus: spi1-bus {
- samsung,pins = "gpb-4", "gpb-6", "gpb-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c5_bus: i2c5-bus {
- samsung,pins = "gpb-2", "gpb-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2s1_bus: i2s1-bus {
- samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
- "gpc0-4";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2s2_bus: i2s2-bus {
- samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
- "gpc1-4";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- pcm2_bus: pcm2-bus {
- samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
- "gpc1-4";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c6_bus: i2c6-bus {
- samsung,pins = "gpc1-3", "gpc1-4";
- samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- spi2_bus: spi2-bus {
- samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
- samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- pwm0_out: pwm0-out {
- samsung,pins = "gpd0-0";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- pwm1_out: pwm1-out {
- samsung,pins = "gpd0-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- pwm2_out: pwm2-out {
- samsung,pins = "gpd0-2";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- pwm3_out: pwm3-out {
- samsung,pins = "gpd0-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c7_bus: i2c7-bus {
- samsung,pins = "gpd0-2", "gpd0-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c0_bus: i2c0-bus {
- samsung,pins = "gpd1-0", "gpd1-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c1_bus: i2c1-bus {
- samsung,pins = "gpd1-2", "gpd1-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-};
-
-&pinctrl_1 {
- gpk0: gpk0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpk1: gpk1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpk2: gpk2 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpk3: gpk3 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpl0: gpl0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpm0: gpm0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpm1: gpm1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpm2: gpm2 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpm3: gpm3 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpm4: gpm4 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpx0: gpx0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- interrupt-parent = <&gic>;
- interrupts = <0 32 0>, <0 33 0>, <0 34 0>, <0 35 0>,
- <0 36 0>, <0 37 0>, <0 38 0>, <0 39 0>;
- #interrupt-cells = <2>;
- };
-
- gpx1: gpx1 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- interrupt-parent = <&gic>;
- interrupts = <0 40 0>, <0 41 0>, <0 42 0>, <0 43 0>,
- <0 44 0>, <0 45 0>, <0 46 0>, <0 47 0>;
- #interrupt-cells = <2>;
- };
-
- gpx2: gpx2 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- gpx3: gpx3 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- sd0_clk: sd0-clk {
- samsung,pins = "gpk0-0";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd0_cmd: sd0-cmd {
- samsung,pins = "gpk0-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd0_cd: sd0-cd {
- samsung,pins = "gpk0-2";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd0_rdqs: sd0-rdqs {
- samsung,pins = "gpk0-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd0_bus1: sd0-bus-width1 {
- samsung,pins = "gpk0-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd0_bus4: sd0-bus-width4 {
- samsung,pins = "gpk0-4", "gpk0-5", "gpk0-6";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd0_bus8: sd0-bus-width8 {
- samsung,pins = "gpl0-0", "gpl0-1", "gpl0-2", "gpl0-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd1_clk: sd1-clk {
- samsung,pins = "gpk1-0";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd1_cmd: sd1-cmd {
- samsung,pins = "gpk1-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd1_cd: sd1-cd {
- samsung,pins = "gpk1-2";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd1_bus1: sd1-bus-width1 {
- samsung,pins = "gpk1-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd1_bus4: sd1-bus-width4 {
- samsung,pins = "gpk1-4", "gpk1-5", "gpk1-6";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd2_clk: sd2-clk {
- samsung,pins = "gpk2-0";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd2_cmd: sd2-cmd {
- samsung,pins = "gpk2-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd2_cd: sd2-cd {
- samsung,pins = "gpk2-2";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd2_bus1: sd2-bus-width1 {
- samsung,pins = "gpk2-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- sd2_bus4: sd2-bus-width4 {
- samsung,pins = "gpk2-4", "gpk2-5", "gpk2-6";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- cam_port_b_io: cam-port-b-io {
- samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
- "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
- "gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- cam_port_b_clk_active: cam-port-b-clk-active {
- samsung,pins = "gpm2-2";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
-
- cam_port_b_clk_idle: cam-port-b-clk-idle {
- samsung,pins = "gpm2-2";
- samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- fimc_is_i2c0: fimc-is-i2c0 {
- samsung,pins = "gpm4-0", "gpm4-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- fimc_is_i2c1: fimc-is-i2c1 {
- samsung,pins = "gpm4-2", "gpm4-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- fimc_is_uart: fimc-is-uart {
- samsung,pins = "gpm3-5", "gpm3-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-};
-
-&pinctrl_2 {
- gpz: gpz {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- i2s0_bus: i2s0-bus {
- samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
- "gpz-4", "gpz-5", "gpz-6";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-};
diff --git a/arch/arm/boot/dts/exynos4415.dtsi b/arch/arm/boot/dts/exynos4415.dtsi
deleted file mode 100644
index 3c40f8a956dd..000000000000
--- a/arch/arm/boot/dts/exynos4415.dtsi
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * Samsung's Exynos4415 SoC device tree source
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Samsung's Exynos4415 SoC device nodes are listed in this file. Exynos4415
- * based board files can include this file and provide values for board
- * specific bindings.
- *
- * Note: This file does not include device nodes for all the controllers in
- * Exynos4415 SoC. As device tree coverage for Exynos4415 increases, additional
- * nodes can be added to this file.
- *
- * 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/clock/exynos4415.h>
-#include <dt-bindings/clock/exynos-audss-clk.h>
-
-/ {
- compatible = "samsung,exynos4415";
- interrupt-parent = <&gic>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- pinctrl0 = &pinctrl_0;
- pinctrl1 = &pinctrl_1;
- pinctrl2 = &pinctrl_2;
- mshc0 = &mshc_0;
- mshc1 = &mshc_1;
- mshc2 = &mshc_2;
- spi0 = &spi_0;
- spi1 = &spi_1;
- spi2 = &spi_2;
- i2c0 = &i2c_0;
- i2c1 = &i2c_1;
- i2c2 = &i2c_2;
- i2c3 = &i2c_3;
- i2c4 = &i2c_4;
- i2c5 = &i2c_5;
- i2c6 = &i2c_6;
- i2c7 = &i2c_7;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu0: cpu@a00 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0xa00>;
- clock-frequency = <1600000000>;
- };
-
- cpu1: cpu@a01 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0xa01>;
- clock-frequency = <1600000000>;
- };
-
- cpu2: cpu@a02 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0xa02>;
- clock-frequency = <1600000000>;
- };
-
- cpu3: cpu@a03 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0xa03>;
- clock-frequency = <1600000000>;
- };
- };
-
- soc: soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- sysram@02020000 {
- compatible = "mmio-sram";
- reg = <0x02020000 0x50000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x02020000 0x50000>;
-
- smp-sysram@0 {
- compatible = "samsung,exynos4210-sysram";
- reg = <0x0 0x1000>;
- };
-
- smp-sysram@4f000 {
- compatible = "samsung,exynos4210-sysram-ns";
- reg = <0x4f000 0x1000>;
- };
- };
-
- pinctrl_2: pinctrl@03860000 {
- compatible = "samsung,exynos4415-pinctrl";
- reg = <0x03860000 0x1000>;
- interrupts = <0 242 0>;
- };
-
- chipid@10000000 {
- compatible = "samsung,exynos4210-chipid";
- reg = <0x10000000 0x100>;
- };
-
- sysreg_system_controller: syscon@10010000 {
- compatible = "samsung,exynos4-sysreg", "syscon";
- reg = <0x10010000 0x400>;
- };
-
- pmu_system_controller: system-controller@10020000 {
- compatible = "samsung,exynos4415-pmu", "syscon";
- reg = <0x10020000 0x4000>;
- };
-
- mipi_phy: video-phy@10020710 {
- compatible = "samsung,s5pv210-mipi-video-phy";
- #phy-cells = <1>;
- syscon = <&pmu_system_controller>;
- };
-
- pd_cam: cam-power-domain@10024000 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x10024000 0x20>;
- #power-domain-cells = <0>;
- };
-
- pd_tv: tv-power-domain@10024020 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x10024020 0x20>;
- #power-domain-cells = <0>;
- };
-
- pd_mfc: mfc-power-domain@10024040 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x10024040 0x20>;
- #power-domain-cells = <0>;
- };
-
- pd_g3d: g3d-power-domain@10024060 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x10024060 0x20>;
- #power-domain-cells = <0>;
- };
-
- pd_lcd0: lcd0-power-domain@10024080 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x10024080 0x20>;
- #power-domain-cells = <0>;
- };
-
- pd_isp0: isp0-power-domain@100240A0 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x100240A0 0x20>;
- #power-domain-cells = <0>;
- };
-
- pd_isp1: isp1-power-domain@100240E0 {
- compatible = "samsung,exynos4210-pd";
- reg = <0x100240E0 0x20>;
- #power-domain-cells = <0>;
- };
-
- cmu: clock-controller@10030000 {
- compatible = "samsung,exynos4415-cmu";
- reg = <0x10030000 0x18000>;
- #clock-cells = <1>;
- };
-
- rtc: rtc@10070000 {
- compatible = "samsung,s3c6410-rtc";
- reg = <0x10070000 0x100>;
- interrupts = <0 73 0>, <0 74 0>;
- status = "disabled";
- };
-
- mct@10050000 {
- compatible = "samsung,exynos4210-mct";
- reg = <0x10050000 0x800>;
- interrupts = <0 218 0>, <0 219 0>, <0 220 0>, <0 221 0>,
- <0 223 0>, <0 226 0>, <0 227 0>, <0 228 0>;
- clocks = <&cmu CLK_FIN_PLL>, <&cmu CLK_MCT>;
- clock-names = "fin_pll", "mct";
- };
-
- gic: interrupt-controller@10481000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x10481000 0x1000>,
- <0x10482000 0x1000>,
- <0x10484000 0x2000>,
- <0x10486000 0x2000>;
- interrupts = <1 9 0xf04>;
- };
-
- l2c: l2-cache-controller@10502000 {
- compatible = "arm,pl310-cache";
- reg = <0x10502000 0x1000>;
- cache-unified;
- cache-level = <2>;
- arm,tag-latency = <2 2 1>;
- arm,data-latency = <3 2 1>;
- arm,double-linefill = <1>;
- arm,double-linefill-incr = <0>;
- arm,double-linefill-wrap = <1>;
- arm,prefetch-drop = <1>;
- arm,prefetch-offset = <7>;
- };
-
- cmu_dmc: clock-controller@105C0000 {
- compatible = "samsung,exynos4415-cmu-dmc";
- reg = <0x105C0000 0x3000>;
- #clock-cells = <1>;
- };
-
- pinctrl_1: pinctrl@11000000 {
- compatible = "samsung,exynos4415-pinctrl";
- reg = <0x11000000 0x1000>;
- interrupts = <0 225 0>;
-
- wakeup-interrupt-controller {
- compatible = "samsung,exynos4210-wakeup-eint";
- interrupt-parent = <&gic>;
- interrupts = <0 48 0>;
- };
- };
-
- pinctrl_0: pinctrl@11400000 {
- compatible = "samsung,exynos4415-pinctrl";
- reg = <0x11400000 0x1000>;
- interrupts = <0 240 0>;
- };
-
- fimd: fimd@11C00000 {
- compatible = "samsung,exynos4415-fimd";
- reg = <0x11C00000 0x30000>;
- interrupt-names = "fifo", "vsync", "lcd_sys";
- interrupts = <0 84 0>, <0 85 0>, <0 86 0>;
- clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
- clock-names = "sclk_fimd", "fimd";
- samsung,power-domain = <&pd_lcd0>;
- iommus = <&sysmmu_fimd0>;
- samsung,sysreg = <&sysreg_system_controller>;
- status = "disabled";
- };
-
- dsi_0: dsi@11C80000 {
- compatible = "samsung,exynos4415-mipi-dsi";
- reg = <0x11C80000 0x10000>;
- interrupts = <0 83 0>;
- samsung,phy-type = <0>;
- samsung,power-domain = <&pd_lcd0>;
- phys = <&mipi_phy 1>;
- phy-names = "dsim";
- clocks = <&cmu CLK_DSIM0>, <&cmu CLK_SCLK_MIPI0>;
- clock-names = "bus_clk", "pll_clk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- sysmmu_fimd0: sysmmu@11E20000 {
- compatible = "samsung,exynos-sysmmu";
- reg = <0x11e20000 0x1000>;
- interrupts = <0 80 0>, <0 81 0>;
- clock-names = "sysmmu", "master";
- clocks = <&cmu CLK_SMMUFIMD0>, <&cmu CLK_FIMD0>;
- power-domains = <&pd_lcd0>;
- #iommu-cells = <0>;
- };
-
- hsotg: hsotg@12480000 {
- compatible = "samsung,s3c6400-hsotg";
- reg = <0x12480000 0x20000>;
- interrupts = <0 141 0>;
- clocks = <&cmu CLK_USBDEVICE>;
- clock-names = "otg";
- phys = <&exynos_usbphy 0>;
- phy-names = "usb2-phy";
- status = "disabled";
- };
-
- mshc_0: mshc@12510000 {
- compatible = "samsung,exynos5250-dw-mshc";
- reg = <0x12510000 0x1000>;
- interrupts = <0 142 0>;
- clocks = <&cmu CLK_SDMMC0>, <&cmu CLK_SCLK_MMC0>;
- clock-names = "biu", "ciu";
- fifo-depth = <0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- mshc_1: mshc@12520000 {
- compatible = "samsung,exynos5250-dw-mshc";
- reg = <0x12520000 0x1000>;
- interrupts = <0 143 0>;
- clocks = <&cmu CLK_SDMMC1>, <&cmu CLK_SCLK_MMC1>;
- clock-names = "biu", "ciu";
- fifo-depth = <0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- mshc_2: mshc@12530000 {
- compatible = "samsung,exynos5250-dw-mshc";
- reg = <0x12530000 0x1000>;
- interrupts = <0 144 0>;
- clocks = <&cmu CLK_SDMMC2>, <&cmu CLK_SCLK_MMC2>;
- clock-names = "biu", "ciu";
- fifo-depth = <0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- ehci: ehci@12580000 {
- compatible = "samsung,exynos4210-ehci";
- reg = <0x12580000 0x100>;
- interrupts = <0 140 0>;
- clocks = <&cmu CLK_USBHOST>;
- clock-names = "usbhost";
- status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&exynos_usbphy 1>;
- status = "disabled";
- };
- port@1 {
- reg = <1>;
- phys = <&exynos_usbphy 2>;
- status = "disabled";
- };
- port@2 {
- reg = <2>;
- phys = <&exynos_usbphy 3>;
- status = "disabled";
- };
- };
-
- ohci: ohci@12590000 {
- compatible = "samsung,exynos4210-ohci";
- reg = <0x12590000 0x100>;
- interrupts = <0 140 0>;
- clocks = <&cmu CLK_USBHOST>;
- clock-names = "usbhost";
- status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- phys = <&exynos_usbphy 1>;
- status = "disabled";
- };
- };
-
- exynos_usbphy: exynos-usbphy@125B0000 {
- compatible = "samsung,exynos4x12-usb2-phy";
- reg = <0x125B0000 0x100>;
- samsung,pmureg-phandle = <&pmu_system_controller>;
- samsung,sysreg-phandle = <&sysreg_system_controller>;
- clocks = <&cmu CLK_USBDEVICE>, <&xusbxti>;
- clock-names = "phy", "ref";
- #phy-cells = <1>;
- status = "disabled";
- };
-
- amba {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&gic>;
- ranges;
-
- pdma0: pdma@12680000 {
- compatible = "arm,pl330", "arm,primecell";
- reg = <0x12680000 0x1000>;
- interrupts = <0 138 0>;
- clocks = <&cmu CLK_PDMA0>;
- clock-names = "apb_pclk";
- #dma-cells = <1>;
- #dma-channels = <8>;
- #dma-requests = <32>;
- };
-
- pdma1: pdma@12690000 {
- compatible = "arm,pl330", "arm,primecell";
- reg = <0x12690000 0x1000>;
- interrupts = <0 139 0>;
- clocks = <&cmu CLK_PDMA1>;
- clock-names = "apb_pclk";
- #dma-cells = <1>;
- #dma-channels = <8>;
- #dma-requests = <32>;
- };
- };
-
- adc: adc@126C0000 {
- compatible = "samsung,exynos3250-adc",
- "samsung,exynos-adc-v2";
- reg = <0x126C0000 0x100>, <0x10020718 0x4>;
- interrupts = <0 137 0>;
- clock-names = "adc", "sclk";
- clocks = <&cmu CLK_TSADC>, <&cmu CLK_SCLK_TSADC>;
- #io-channel-cells = <1>;
- io-channel-ranges;
- status = "disabled";
- };
-
- serial_0: serial@13800000 {
- compatible = "samsung,exynos4210-uart";
- reg = <0x13800000 0x100>;
- interrupts = <0 109 0>;
- clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
- clock-names = "uart", "clk_uart_baud0";
- status = "disabled";
- };
-
- serial_1: serial@13810000 {
- compatible = "samsung,exynos4210-uart";
- reg = <0x13810000 0x100>;
- interrupts = <0 110 0>;
- clocks = <&cmu CLK_UART1>, <&cmu CLK_SCLK_UART1>;
- clock-names = "uart", "clk_uart_baud0";
- status = "disabled";
- };
-
- serial_2: serial@13820000 {
- compatible = "samsung,exynos4210-uart";
- reg = <0x13820000 0x100>;
- interrupts = <0 111 0>;
- clocks = <&cmu CLK_UART2>, <&cmu CLK_SCLK_UART2>;
- clock-names = "uart", "clk_uart_baud0";
- status = "disabled";
- };
-
- serial_3: serial@13830000 {
- compatible = "samsung,exynos4210-uart";
- reg = <0x13830000 0x100>;
- interrupts = <0 112 0>;
- clocks = <&cmu CLK_UART3>, <&cmu CLK_SCLK_UART3>;
- clock-names = "uart", "clk_uart_baud0";
- status = "disabled";
- };
-
- i2c_0: i2c@13860000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x13860000 0x100>;
- interrupts = <0 113 0>;
- clocks = <&cmu CLK_I2C0>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_bus>;
- status = "disabled";
- };
-
- i2c_1: i2c@13870000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x13870000 0x100>;
- interrupts = <0 114 0>;
- clocks = <&cmu CLK_I2C1>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_bus>;
- status = "disabled";
- };
-
- i2c_2: i2c@13880000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x13880000 0x100>;
- interrupts = <0 115 0>;
- clocks = <&cmu CLK_I2C2>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_bus>;
- status = "disabled";
- };
-
- i2c_3: i2c@13890000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x13890000 0x100>;
- interrupts = <0 116 0>;
- clocks = <&cmu CLK_I2C3>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c3_bus>;
- status = "disabled";
- };
-
- i2c_4: i2c@138A0000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x138A0000 0x100>;
- interrupts = <0 117 0>;
- clocks = <&cmu CLK_I2C4>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c4_bus>;
- status = "disabled";
- };
-
- i2c_5: i2c@138B0000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x138B0000 0x100>;
- interrupts = <0 118 0>;
- clocks = <&cmu CLK_I2C5>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c5_bus>;
- status = "disabled";
- };
-
- i2c_6: i2c@138C0000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x138C0000 0x100>;
- interrupts = <0 119 0>;
- clocks = <&cmu CLK_I2C6>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c6_bus>;
- status = "disabled";
- };
-
- i2c_7: i2c@138D0000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "samsung,s3c2440-i2c";
- reg = <0x138D0000 0x100>;
- interrupts = <0 120 0>;
- clocks = <&cmu CLK_I2C7>;
- clock-names = "i2c";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c7_bus>;
- status = "disabled";
- };
-
- spi_0: spi@13920000 {
- compatible = "samsung,exynos4210-spi";
- reg = <0x13920000 0x100>;
- interrupts = <0 121 0>;
- dmas = <&pdma0 7>, <&pdma0 6>;
- dma-names = "tx", "rx";
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&cmu CLK_SPI0>, <&cmu CLK_SCLK_SPI0>;
- clock-names = "spi", "spi_busclk0";
- samsung,spi-src-clk = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_bus>;
- status = "disabled";
- };
-
- spi_1: spi@13930000 {
- compatible = "samsung,exynos4210-spi";
- reg = <0x13930000 0x100>;
- interrupts = <0 122 0>;
- dmas = <&pdma1 7>, <&pdma1 6>;
- dma-names = "tx", "rx";
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&cmu CLK_SPI1>, <&cmu CLK_SCLK_SPI1>;
- clock-names = "spi", "spi_busclk0";
- samsung,spi-src-clk = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_bus>;
- status = "disabled";
- };
-
- spi_2: spi@13940000 {
- compatible = "samsung,exynos4210-spi";
- reg = <0x13940000 0x100>;
- interrupts = <0 123 0>;
- dmas = <&pdma0 9>, <&pdma0 8>;
- dma-names = "tx", "rx";
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&cmu CLK_SPI2>, <&cmu CLK_SCLK_SPI2>;
- clock-names = "spi", "spi_busclk0";
- samsung,spi-src-clk = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi2_bus>;
- status = "disabled";
- };
-
- clock_audss: clock-controller@03810000 {
- compatible = "samsung,exynos4210-audss-clock";
- reg = <0x03810000 0x0C>;
- #clock-cells = <1>;
- };
-
- i2s0: i2s@3830000 {
- compatible = "samsung,s5pv210-i2s";
- reg = <0x03830000 0x100>;
- interrupts = <0 124 0>;
- clocks = <&clock_audss EXYNOS_I2S_BUS>,
- <&clock_audss EXYNOS_SCLK_I2S>;
- clock-names = "iis", "i2s_opclk0";
- dmas = <&pdma1 10>, <&pdma1 9>, <&pdma1 8>;
- dma-names = "tx", "rx", "tx-sec";
- pinctrl-names = "default";
- pinctrl-0 = <&i2s0_bus>;
- samsung,idma-addr = <0x03000000>;
- status = "disabled";
- };
-
- pwm: pwm@139D0000 {
- compatible = "samsung,exynos4210-pwm";
- reg = <0x139D0000 0x1000>;
- interrupts = <0 104 0>, <0 105 0>, <0 106 0>,
- <0 107 0>, <0 108 0>;
- #pwm-cells = <3>;
- status = "disabled";
- };
-
- pmu {
- compatible = "arm,cortex-a9-pmu";
- interrupts = <0 18 0>, <0 19 0>, <0 20 0>, <0 21 0>;
- };
- };
-};
-
-#include "exynos4415-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
index a56bf9b1a412..2f866f6e5838 100644
--- a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
@@ -572,8 +572,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
- interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
- <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
};
@@ -583,8 +589,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
- interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
- <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 3394bdcf10ae..85a7122658f1 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -88,11 +88,11 @@
#interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
- interrupt-map = <0 &gic 0 57 0>,
+ interrupt-map = <0 &gic 0 57 IRQ_TYPE_LEVEL_HIGH>,
<1 &combiner 12 5>,
<2 &combiner 12 6>,
<3 &combiner 12 7>,
- <4 &gic 1 12 0>;
+ <4 &gic 1 12 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -112,7 +112,7 @@
g2d: g2d@10800000 {
compatible = "samsung,exynos4212-g2d";
reg = <0x10800000 0x1000>;
- interrupts = <0 89 0>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
clock-names = "sclk_fimg2d", "fimg2d";
iommus = <&sysmmu_g2d>;
@@ -127,7 +127,7 @@
fimc_lite_0: fimc-lite@12390000 {
compatible = "samsung,exynos4212-fimc-lite";
reg = <0x12390000 0x1000>;
- interrupts = <0 105 0>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE0>;
clock-names = "flite";
@@ -138,7 +138,7 @@
fimc_lite_1: fimc-lite@123A0000 {
compatible = "samsung,exynos4212-fimc-lite";
reg = <0x123A0000 0x1000>;
- interrupts = <0 106 0>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE1>;
clock-names = "flite";
@@ -147,9 +147,10 @@
};
fimc_is: fimc-is@12000000 {
- compatible = "samsung,exynos4212-fimc-is", "simple-bus";
+ compatible = "samsung,exynos4212-fimc-is";
reg = <0x12000000 0x260000>;
- interrupts = <0 90 0>, <0 95 0>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE0>,
<&clock CLK_FIMC_LITE1>, <&clock CLK_PPMUISPX>,
@@ -200,7 +201,7 @@
mshc_0: mmc@12550000 {
compatible = "samsung,exynos4412-dw-mshc";
reg = <0x12550000 0x1000>;
- interrupts = <0 77 0>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
fifo-depth = <0x80>;
@@ -461,11 +462,26 @@
};
&combiner {
- interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
- <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
- <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
- <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
- <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
};
&exynos_usbphy {
@@ -529,18 +545,18 @@
&pinctrl_0 {
compatible = "samsung,exynos4x12-pinctrl";
reg = <0x11400000 0x1000>;
- interrupts = <0 47 0>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
};
&pinctrl_1 {
compatible = "samsung,exynos4x12-pinctrl";
reg = <0x11000000 0x1000>;
- interrupts = <0 46 0>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
wakup_eint: wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -554,7 +570,7 @@
&pinctrl_3 {
compatible = "samsung,exynos4x12-pinctrl";
reg = <0x106E0000 0x1000>;
- interrupts = <0 72 0>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
};
&pmu_system_controller {
diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 8f06609879f5..7fd870ee5093 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -13,6 +13,8 @@
* published by the Free Software Foundation.
*/
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
#include "exynos-syscon-restart.dtsi"
/ {
@@ -53,14 +55,38 @@
interrupt-controller;
samsung,combiner-nr = <32>;
reg = <0x10440000 0x1000>;
- interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
- <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
- <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
- <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
- <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
- <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
- <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
- <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 2 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>,
+ <0 4 IRQ_TYPE_LEVEL_HIGH>,
+ <0 5 IRQ_TYPE_LEVEL_HIGH>,
+ <0 6 IRQ_TYPE_LEVEL_HIGH>,
+ <0 7 IRQ_TYPE_LEVEL_HIGH>,
+ <0 8 IRQ_TYPE_LEVEL_HIGH>,
+ <0 9 IRQ_TYPE_LEVEL_HIGH>,
+ <0 10 IRQ_TYPE_LEVEL_HIGH>,
+ <0 11 IRQ_TYPE_LEVEL_HIGH>,
+ <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 13 IRQ_TYPE_LEVEL_HIGH>,
+ <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 IRQ_TYPE_LEVEL_HIGH>,
+ <0 16 IRQ_TYPE_LEVEL_HIGH>,
+ <0 17 IRQ_TYPE_LEVEL_HIGH>,
+ <0 18 IRQ_TYPE_LEVEL_HIGH>,
+ <0 19 IRQ_TYPE_LEVEL_HIGH>,
+ <0 20 IRQ_TYPE_LEVEL_HIGH>,
+ <0 21 IRQ_TYPE_LEVEL_HIGH>,
+ <0 22 IRQ_TYPE_LEVEL_HIGH>,
+ <0 23 IRQ_TYPE_LEVEL_HIGH>,
+ <0 24 IRQ_TYPE_LEVEL_HIGH>,
+ <0 25 IRQ_TYPE_LEVEL_HIGH>,
+ <0 26 IRQ_TYPE_LEVEL_HIGH>,
+ <0 27 IRQ_TYPE_LEVEL_HIGH>,
+ <0 28 IRQ_TYPE_LEVEL_HIGH>,
+ <0 29 IRQ_TYPE_LEVEL_HIGH>,
+ <0 30 IRQ_TYPE_LEVEL_HIGH>,
+ <0 31 IRQ_TYPE_LEVEL_HIGH>;
};
gic: interrupt-controller@10481000 {
@@ -71,7 +97,8 @@
<0x10482000 0x1000>,
<0x10484000 0x2000>,
<0x10486000 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
sysreg_system_controller: syscon@10050000 {
@@ -82,31 +109,31 @@
serial_0: serial@12C00000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C00000 0x100>;
- interrupts = <0 51 0>;
+ interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
};
serial_1: serial@12C10000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C10000 0x100>;
- interrupts = <0 52 0>;
+ interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
};
serial_2: serial@12C20000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C20000 0x100>;
- interrupts = <0 53 0>;
+ interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>;
};
serial_3: serial@12C30000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C30000 0x100>;
- interrupts = <0 54 0>;
+ interrupts = <0 54 IRQ_TYPE_LEVEL_HIGH>;
};
i2c_0: i2c@12C60000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C60000 0x100>;
- interrupts = <0 56 0>;
+ interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
samsung,sysreg-phandle = <&sysreg_system_controller>;
@@ -116,7 +143,7 @@
i2c_1: i2c@12C70000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C70000 0x100>;
- interrupts = <0 57 0>;
+ interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
samsung,sysreg-phandle = <&sysreg_system_controller>;
@@ -126,7 +153,7 @@
i2c_2: i2c@12C80000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C80000 0x100>;
- interrupts = <0 58 0>;
+ interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
samsung,sysreg-phandle = <&sysreg_system_controller>;
@@ -136,7 +163,7 @@
i2c_3: i2c@12C90000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C90000 0x100>;
- interrupts = <0 59 0>;
+ interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
samsung,sysreg-phandle = <&sysreg_system_controller>;
@@ -153,7 +180,8 @@
rtc: rtc@101E0000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x101E0000 0x100>;
- interrupts = <0 43 0>, <0 44 0>;
+ interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>,
+ <0 44 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
index d5d51916bb74..8f3a80430748 100644
--- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -523,6 +523,7 @@
status = "okay";
};
+/* eMMC flash */
&mmc_0 {
status = "okay";
num-slots = <1>;
@@ -536,6 +537,7 @@
cap-mmc-highspeed;
};
+/* uSD card */
&mmc_2 {
status = "okay";
num-slots = <1>;
@@ -553,6 +555,8 @@
/*
* On Snow we've got SIP WiFi and so can keep drive strengths low to
* reduce EMI.
+ *
+ * WiFi SDIO module
*/
&mmc_3 {
status = "okay";
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index f7357d99b47c..b6d7444d8585 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -181,8 +181,8 @@
<0x1 0 &combiner 23 4>,
<0x2 0 &combiner 25 2>,
<0x3 0 &combiner 25 3>,
- <0x4 0 &gic 0 120 0>,
- <0x5 0 &gic 0 121 0>;
+ <0x4 0 &gic 0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <0x5 0 &gic 0 121 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -195,31 +195,31 @@
pinctrl_0: pinctrl@11400000 {
compatible = "samsung,exynos5250-pinctrl";
reg = <0x11400000 0x1000>;
- interrupts = <0 46 0>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
wakup_eint: wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
};
pinctrl_1: pinctrl@13400000 {
compatible = "samsung,exynos5250-pinctrl";
reg = <0x13400000 0x1000>;
- interrupts = <0 45 0>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_2: pinctrl@10d10000 {
compatible = "samsung,exynos5250-pinctrl";
reg = <0x10d10000 0x1000>;
- interrupts = <0 50 0>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_3: pinctrl@03860000 {
compatible = "samsung,exynos5250-pinctrl";
reg = <0x03860000 0x1000>;
- interrupts = <0 47 0>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
};
pmu_system_controller: system-controller@10040000 {
@@ -236,7 +236,7 @@
watchdog@101D0000 {
compatible = "samsung,exynos5250-wdt";
reg = <0x101D0000 0x100>;
- interrupts = <0 42 0>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_WDT>;
clock-names = "watchdog";
samsung,syscon-phandle = <&pmu_system_controller>;
@@ -245,7 +245,7 @@
g2d@10850000 {
compatible = "samsung,exynos5250-g2d";
reg = <0x10850000 0x1000>;
- interrupts = <0 91 0>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_G2D>;
clock-names = "fimg2d";
iommus = <&sysmmu_g2d>;
@@ -254,7 +254,7 @@
mfc: codec@11000000 {
compatible = "samsung,mfc-v6";
reg = <0x11000000 0x10000>;
- interrupts = <0 96 0>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_mfc>;
clocks = <&clock CLK_MFC>;
clock-names = "mfc";
@@ -265,7 +265,7 @@
rotator: rotator@11C00000 {
compatible = "samsung,exynos5250-rotator";
reg = <0x11C00000 0x64>;
- interrupts = <0 84 0>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_ROTATOR>;
clock-names = "rotator";
iommus = <&sysmmu_rotator>;
@@ -274,7 +274,7 @@
tmu: tmu@10060000 {
compatible = "samsung,exynos5250-tmu";
reg = <0x10060000 0x100>;
- interrupts = <0 65 0>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -284,7 +284,7 @@
compatible = "snps,dwc-ahci";
samsung,sata-freq = <66>;
reg = <0x122F0000 0x1ff>;
- interrupts = <0 115 0>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SATA>, <&clock CLK_SCLK_SATA>;
clock-names = "sata", "sclk_sata";
phys = <&sata_phy>;
@@ -306,7 +306,7 @@
i2c_4: i2c@12CA0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CA0000 0x100>;
- interrupts = <0 60 0>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_I2C4>;
@@ -319,7 +319,7 @@
i2c_5: i2c@12CB0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CB0000 0x100>;
- interrupts = <0 61 0>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_I2C5>;
@@ -332,7 +332,7 @@
i2c_6: i2c@12CC0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CC0000 0x100>;
- interrupts = <0 62 0>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_I2C6>;
@@ -345,7 +345,7 @@
i2c_7: i2c@12CD0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CD0000 0x100>;
- interrupts = <0 63 0>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_I2C7>;
@@ -358,7 +358,7 @@
i2c_8: i2c@12CE0000 {
compatible = "samsung,s3c2440-hdmiphy-i2c";
reg = <0x12CE0000 0x1000>;
- interrupts = <0 64 0>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_I2C_HDMI>;
@@ -380,7 +380,7 @@
compatible = "samsung,exynos4210-spi";
status = "disabled";
reg = <0x12d20000 0x100>;
- interrupts = <0 66 0>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 5
&pdma0 4>;
dma-names = "tx", "rx";
@@ -396,7 +396,7 @@
compatible = "samsung,exynos4210-spi";
status = "disabled";
reg = <0x12d30000 0x100>;
- interrupts = <0 67 0>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma1 5
&pdma1 4>;
dma-names = "tx", "rx";
@@ -412,7 +412,7 @@
compatible = "samsung,exynos4210-spi";
status = "disabled";
reg = <0x12d40000 0x100>;
- interrupts = <0 68 0>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 7
&pdma0 6>;
dma-names = "tx", "rx";
@@ -426,7 +426,7 @@
mmc_0: mmc@12200000 {
compatible = "samsung,exynos5250-dw-mshc";
- interrupts = <0 75 0>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12200000 0x1000>;
@@ -438,7 +438,7 @@
mmc_1: mmc@12210000 {
compatible = "samsung,exynos5250-dw-mshc";
- interrupts = <0 76 0>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12210000 0x1000>;
@@ -450,7 +450,7 @@
mmc_2: mmc@12220000 {
compatible = "samsung,exynos5250-dw-mshc";
- interrupts = <0 77 0>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12220000 0x1000>;
@@ -463,7 +463,7 @@
mmc_3: mmc@12230000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12230000 0x1000>;
- interrupts = <0 78 0>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
@@ -526,7 +526,7 @@
usbdrd_dwc3: dwc3@12000000 {
compatible = "synopsys,dwc3";
reg = <0x12000000 0x10000>;
- interrupts = <0 72 0>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usbdrd_phy 0>, <&usbdrd_phy 1>;
phy-names = "usb2-phy", "usb3-phy";
};
@@ -544,7 +544,7 @@
ehci: usb@12110000 {
compatible = "samsung,exynos4210-ehci";
reg = <0x12110000 0x100>;
- interrupts = <0 71 0>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB2>;
clock-names = "usbhost";
@@ -559,7 +559,7 @@
ohci: usb@12120000 {
compatible = "samsung,exynos4210-ohci";
reg = <0x12120000 0x100>;
- interrupts = <0 71 0>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB2>;
clock-names = "usbhost";
@@ -591,7 +591,7 @@
pdma0: pdma@121A0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121A0000 0x1000>;
- interrupts = <0 34 0>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -602,7 +602,7 @@
pdma1: pdma@121B0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121B0000 0x1000>;
- interrupts = <0 35 0>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -613,7 +613,7 @@
mdma0: mdma@10800000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10800000 0x1000>;
- interrupts = <0 33 0>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -624,7 +624,7 @@
mdma1: mdma@11C10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11C10000 0x1000>;
- interrupts = <0 124 0>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -636,7 +636,7 @@
gsc_0: gsc@13e00000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
- interrupts = <0 85 0>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
@@ -646,7 +646,7 @@
gsc_1: gsc@13e10000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e10000 0x1000>;
- interrupts = <0 86 0>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL1>;
clock-names = "gscl";
@@ -656,7 +656,7 @@
gsc_2: gsc@13e20000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e20000 0x1000>;
- interrupts = <0 87 0>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL2>;
clock-names = "gscl";
@@ -666,7 +666,7 @@
gsc_3: gsc@13e30000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e30000 0x1000>;
- interrupts = <0 88 0>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL3>;
clock-names = "gscl";
@@ -677,7 +677,7 @@
compatible = "samsung,exynos4212-hdmi";
reg = <0x14530000 0x70000>;
power-domains = <&pd_disp1>;
- interrupts = <0 95 0>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
<&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
<&clock CLK_MOUT_HDMI>;
@@ -690,7 +690,7 @@
compatible = "samsung,exynos5250-mixer";
reg = <0x14450000 0x10000>;
power-domains = <&pd_disp1>;
- interrupts = <0 94 0>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
<&clock CLK_SCLK_HDMI>;
clock-names = "mixer", "hdmi", "sclk_hdmi";
@@ -706,7 +706,7 @@
adc: adc@12D10000 {
compatible = "samsung,exynos-adc-v1";
reg = <0x12D10000 0x100>;
- interrupts = <0 106 0>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_ADC>;
clock-names = "adc";
#io-channel-cells = <1>;
@@ -718,7 +718,7 @@
sss@10830000 {
compatible = "samsung,exynos4210-secss";
reg = <0x10830000 0x300>;
- interrupts = <0 112 0>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SSS>;
clock-names = "secss";
};
diff --git a/arch/arm/boot/dts/exynos5260.dtsi b/arch/arm/boot/dts/exynos5260.dtsi
index a86a4898d077..5818718618b1 100644
--- a/arch/arm/boot/dts/exynos5260.dtsi
+++ b/arch/arm/boot/dts/exynos5260.dtsi
@@ -10,6 +10,8 @@
*/
#include <dt-bindings/clock/exynos5260-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
compatible = "samsung,exynos5260", "samsung,exynos5";
@@ -168,7 +170,8 @@
<0x10482000 0x1000>,
<0x10484000 0x2000>,
<0x10486000 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
chipid: chipid@10000000 {
@@ -181,10 +184,18 @@
reg = <0x100B0000 0x1000>;
clocks = <&fin_pll>, <&clock_peri PERI_CLK_MCT>;
clock-names = "fin_pll", "mct";
- interrupts = <0 104 0>, <0 105 0>, <0 106 0>,
- <0 107 0>, <0 122 0>, <0 123 0>,
- <0 124 0>, <0 125 0>, <0 126 0>,
- <0 127 0>, <0 128 0>, <0 129 0>;
+ 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 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
};
cci: cci@10F00000 {
@@ -210,25 +221,25 @@
pinctrl_0: pinctrl@11600000 {
compatible = "samsung,exynos5260-pinctrl";
reg = <0x11600000 0x1000>;
- interrupts = <0 79 0>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
};
pinctrl_1: pinctrl@12290000 {
compatible = "samsung,exynos5260-pinctrl";
reg = <0x12290000 0x1000>;
- interrupts = <0 157 0>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_2: pinctrl@128B0000 {
compatible = "samsung,exynos5260-pinctrl";
reg = <0x128B0000 0x1000>;
- interrupts = <0 243 0>;
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
};
pmu_system_controller: system-controller@10D50000 {
@@ -239,7 +250,7 @@
uart0: serial@12C00000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C00000 0x100>;
- interrupts = <0 146 0>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peri PERI_CLK_UART0>, <&clock_peri PERI_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
status = "disabled";
@@ -248,7 +259,7 @@
uart1: serial@12C10000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C10000 0x100>;
- interrupts = <0 147 0>;
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peri PERI_CLK_UART1>, <&clock_peri PERI_SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0";
status = "disabled";
@@ -257,7 +268,7 @@
uart2: serial@12C20000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C20000 0x100>;
- interrupts = <0 148 0>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peri PERI_CLK_UART2>, <&clock_peri PERI_SCLK_UART2>;
clock-names = "uart", "clk_uart_baud0";
status = "disabled";
@@ -266,7 +277,7 @@
uart3: serial@12860000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12860000 0x100>;
- interrupts = <0 145 0>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_aud AUD_CLK_AUD_UART>, <&clock_aud AUD_SCLK_AUD_UART>;
clock-names = "uart", "clk_uart_baud0";
status = "disabled";
@@ -275,7 +286,7 @@
mmc_0: mmc@12140000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12140000 0x2000>;
- interrupts = <0 156 0>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock_fsys FSYS_CLK_MMC0>, <&clock_top TOP_SCLK_MMC0>;
@@ -287,7 +298,7 @@
mmc_1: mmc@12150000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12150000 0x2000>;
- interrupts = <0 158 0>;
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock_fsys FSYS_CLK_MMC1>, <&clock_top TOP_SCLK_MMC1>;
@@ -299,7 +310,7 @@
mmc_2: mmc@12160000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12160000 0x2000>;
- interrupts = <0 159 0>;
+ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock_fsys FSYS_CLK_MMC2>, <&clock_top TOP_SCLK_MMC2>;
diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts
index 3c271cb4b2be..c4de1353e5df 100644
--- a/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -15,6 +15,7 @@
#include <dt-bindings/clock/maxim,max77802.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/sound/samsung-i2s.h>
#include "exynos54xx-odroidxu-leds.dtsi"
/ {
@@ -57,6 +58,61 @@
compatible = "samsung,secure-firmware";
reg = <0x02073000 0x1000>;
};
+
+ sound: sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,name = "Odroid-XU";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Speakers", "Speakers";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "Headphone Jack", "MICBIAS",
+ "IN1", "Headphone Jack",
+ "Speakers", "SPKL",
+ "Speakers", "SPKR";
+
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&audi2s0 0>;
+ system-clock-frequency = <19200000>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&max98090>;
+ clocks = <&audi2s0 CLK_I2S_CDCLK>;
+ };
+ };
+};
+
+&audi2s0 {
+ status = "okay";
+};
+
+&clock {
+ clocks = <&fin_pll>;
+ assigned-clocks = <&clock CLK_FOUT_EPLL>;
+ assigned-clock-rates = <192000000>;
+};
+
+&clock_audss {
+ assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>,
+ <&clock_audss EXYNOS_MOUT_I2S>,
+ <&clock_audss EXYNOS_DOUT_SRP>,
+ <&clock_audss EXYNOS_DOUT_AUD_BUS>;
+
+ assigned-clock-parents = <&clock CLK_FOUT_EPLL>,
+ <&clock_audss EXYNOS_MOUT_AUDSS>;
+
+ assigned-clock-rates = <0>,
+ <0>,
+ <96000000>,
+ <19200000>;
};
&cpu0_thermal {
@@ -440,6 +496,19 @@
};
};
+&i2c_1 {
+ status = "okay";
+ max98090: max98090@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupt-parent = <&gpj3>;
+ interrupts = <0 IRQ_TYPE_NONE>;
+ clocks = <&audi2s0 CLK_I2S_CDCLK>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+ };
+};
+
&mmc_0 {
status = "okay";
mmc-pwrseq = <&emmc_pwrseq>;
diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
index a083d23fdee3..ff46a1c27182 100644
--- a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
@@ -615,4 +615,13 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ audi2s0_bus: audi2s0-bus {
+ samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+ "gpz-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
};
diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi
index 137f48464f8b..2b6adafe18e2 100644
--- a/arch/arm/boot/dts/exynos5410.dtsi
+++ b/arch/arm/boot/dts/exynos5410.dtsi
@@ -16,6 +16,7 @@
#include "exynos54xx.dtsi"
#include "exynos-syscon-restart.dtsi"
#include <dt-bindings/clock/exynos5410.h>
+#include <dt-bindings/clock/exynos-audss-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
@@ -82,10 +83,18 @@
#clock-cells = <1>;
};
+ clock_audss: audss-clock-controller@3810000 {
+ compatible = "samsung,exynos5410-audss-clock";
+ reg = <0x03810000 0x0C>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock CLK_FOUT_EPLL>;
+ clock-names = "pll_ref", "pll_in";
+ };
+
tmu_cpu0: tmu@10060000 {
compatible = "samsung,exynos5420-tmu";
reg = <0x10060000 0x100>;
- interrupts = <GIC_SPI 65 0>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -94,7 +103,7 @@
tmu_cpu1: tmu@10064000 {
compatible = "samsung,exynos5420-tmu";
reg = <0x10064000 0x100>;
- interrupts = <GIC_SPI 183 0>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -103,7 +112,7 @@
tmu_cpu2: tmu@10068000 {
compatible = "samsung,exynos5420-tmu";
reg = <0x10068000 0x100>;
- interrupts = <GIC_SPI 184 0>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -112,7 +121,7 @@
tmu_cpu3: tmu@1006c000 {
compatible = "samsung,exynos5420-tmu";
reg = <0x1006c000 0x100>;
- interrupts = <GIC_SPI 185 0>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -121,7 +130,7 @@
mmc_0: mmc@12200000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12200000 0x1000>;
- interrupts = <0 75 0>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_MMC0>, <&clock CLK_SCLK_MMC0>;
@@ -133,7 +142,7 @@
mmc_1: mmc@12210000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12210000 0x1000>;
- interrupts = <0 76 0>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_MMC1>, <&clock CLK_SCLK_MMC1>;
@@ -145,7 +154,7 @@
mmc_2: mmc@12220000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12220000 0x1000>;
- interrupts = <0 77 0>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_MMC2>, <&clock CLK_SCLK_MMC2>;
@@ -157,31 +166,81 @@
pinctrl_0: pinctrl@13400000 {
compatible = "samsung,exynos5410-pinctrl";
reg = <0x13400000 0x1000>;
- interrupts = <0 45 0>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
};
pinctrl_1: pinctrl@14000000 {
compatible = "samsung,exynos5410-pinctrl";
reg = <0x14000000 0x1000>;
- interrupts = <0 46 0>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_2: pinctrl@10d10000 {
compatible = "samsung,exynos5410-pinctrl";
reg = <0x10d10000 0x1000>;
- interrupts = <0 50 0>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_3: pinctrl@03860000 {
compatible = "samsung,exynos5410-pinctrl";
reg = <0x03860000 0x1000>;
- interrupts = <0 47 0>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ pdma0: pdma@12680000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121A0000 0x1000>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clock CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@12690000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x121B0000 0x1000>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clock CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+ };
+
+ audi2s0: i2s@03830000 {
+ compatible = "samsung,exynos5420-i2s";
+ reg = <0x03830000 0x100>;
+ dmas = <&pdma0 10
+ &pdma0 9
+ &pdma0 8>;
+ dma-names = "tx", "rx", "tx-sec";
+ clocks = <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_I2S_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk0";
+ #sound-dai-cells = <1>;
+ samsung,idma-addr = <0x03000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&audi2s0_bus>;
+ status = "disabled";
};
};
@@ -329,7 +388,7 @@
};
&usbdrd_dwc3_1 {
- interrupts = <GIC_SPI 200 0>;
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
};
&usbdrd_phy1 {
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index ec4a00f1ce01..1f964ec35c5e 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -697,6 +697,7 @@
status = "okay";
};
+/* eMMC flash */
&mmc_0 {
status = "okay";
num-slots = <1>;
@@ -714,6 +715,7 @@
bus-width = <8>;
};
+/* WiFi SDIO module */
&mmc_1 {
status = "okay";
num-slots = <1>;
@@ -733,6 +735,7 @@
vqmmc-supply = <&buck10_reg>;
};
+/* uSD card */
&mmc_2 {
status = "okay";
num-slots = <1>;
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 00c4cfa54839..906a1a42a7ea 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -193,7 +193,7 @@
mfc: codec@11000000 {
compatible = "samsung,mfc-v7";
reg = <0x11000000 0x10000>;
- interrupts = <0 96 0>;
+ interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MFC>;
clock-names = "mfc";
power-domains = <&mfc_pd>;
@@ -203,7 +203,7 @@
mmc_0: mmc@12200000 {
compatible = "samsung,exynos5420-dw-mshc-smu";
- interrupts = <0 75 0>;
+ interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12200000 0x2000>;
@@ -215,7 +215,7 @@
mmc_1: mmc@12210000 {
compatible = "samsung,exynos5420-dw-mshc-smu";
- interrupts = <0 76 0>;
+ interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12210000 0x2000>;
@@ -227,7 +227,7 @@
mmc_2: mmc@12220000 {
compatible = "samsung,exynos5420-dw-mshc";
- interrupts = <0 77 0>;
+ interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x12220000 0x1000>;
@@ -320,37 +320,37 @@
pinctrl_0: pinctrl@13400000 {
compatible = "samsung,exynos5420-pinctrl";
reg = <0x13400000 0x1000>;
- interrupts = <0 45 0>;
+ interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
+ interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
};
};
pinctrl_1: pinctrl@13410000 {
compatible = "samsung,exynos5420-pinctrl";
reg = <0x13410000 0x1000>;
- interrupts = <0 78 0>;
+ interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_2: pinctrl@14000000 {
compatible = "samsung,exynos5420-pinctrl";
reg = <0x14000000 0x1000>;
- interrupts = <0 46 0>;
+ interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_3: pinctrl@14010000 {
compatible = "samsung,exynos5420-pinctrl";
reg = <0x14010000 0x1000>;
- interrupts = <0 50 0>;
+ interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_4: pinctrl@03860000 {
compatible = "samsung,exynos5420-pinctrl";
reg = <0x03860000 0x1000>;
- interrupts = <0 47 0>;
+ interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
};
amba {
@@ -363,7 +363,7 @@
adma: adma@03880000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x03880000 0x1000>;
- interrupts = <0 110 0>;
+ interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_audss EXYNOS_ADMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -374,7 +374,7 @@
pdma0: pdma@121A0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121A0000 0x1000>;
- interrupts = <0 34 0>;
+ interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -385,7 +385,7 @@
pdma1: pdma@121B0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121B0000 0x1000>;
- interrupts = <0 35 0>;
+ interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -396,7 +396,7 @@
mdma0: mdma@10800000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10800000 0x1000>;
- interrupts = <0 33 0>;
+ interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -407,7 +407,7 @@
mdma1: mdma@11C10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11C10000 0x1000>;
- interrupts = <0 124 0>;
+ interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -479,7 +479,7 @@
spi_0: spi@12d20000 {
compatible = "samsung,exynos4210-spi";
reg = <0x12d20000 0x100>;
- interrupts = <0 68 0>;
+ interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 5
&pdma0 4>;
dma-names = "tx", "rx";
@@ -495,7 +495,7 @@
spi_1: spi@12d30000 {
compatible = "samsung,exynos4210-spi";
reg = <0x12d30000 0x100>;
- interrupts = <0 69 0>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma1 5
&pdma1 4>;
dma-names = "tx", "rx";
@@ -511,7 +511,7 @@
spi_2: spi@12d40000 {
compatible = "samsung,exynos4210-spi";
reg = <0x12d40000 0x100>;
- interrupts = <0 70 0>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&pdma0 7
&pdma0 6>;
dma-names = "tx", "rx";
@@ -539,7 +539,7 @@
dsi@14500000 {
compatible = "samsung,exynos5410-mipi-dsi";
reg = <0x14500000 0x10000>;
- interrupts = <0 82 0>;
+ interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
phys = <&mipi_phy 1>;
phy-names = "dsim";
clocks = <&clock CLK_DSIM1>, <&clock CLK_SCLK_MIPI1>;
@@ -552,7 +552,7 @@
adc: adc@12D10000 {
compatible = "samsung,exynos-adc-v2";
reg = <0x12D10000 0x100>;
- interrupts = <0 106 0>;
+ interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TSADC>;
clock-names = "adc";
#io-channel-cells = <1>;
@@ -564,7 +564,7 @@
hsi2c_8: i2c@12E00000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12E00000 0x1000>;
- interrupts = <0 87 0>;
+ interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -577,7 +577,7 @@
hsi2c_9: i2c@12E10000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12E10000 0x1000>;
- interrupts = <0 88 0>;
+ interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -590,7 +590,7 @@
hsi2c_10: i2c@12E20000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12E20000 0x1000>;
- interrupts = <0 203 0>;
+ interrupts = <0 203 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -603,7 +603,7 @@
hdmi: hdmi@14530000 {
compatible = "samsung,exynos5420-hdmi";
reg = <0x14530000 0x70000>;
- interrupts = <0 95 0>;
+ interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
<&clock CLK_DOUT_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
<&clock CLK_MOUT_HDMI>;
@@ -622,7 +622,7 @@
mixer: mixer@14450000 {
compatible = "samsung,exynos5420-mixer";
reg = <0x14450000 0x10000>;
- interrupts = <0 94 0>;
+ interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
<&clock CLK_SCLK_HDMI>;
clock-names = "mixer", "hdmi", "sclk_hdmi";
@@ -633,7 +633,7 @@
rotator: rotator@11C00000 {
compatible = "samsung,exynos5250-rotator";
reg = <0x11C00000 0x64>;
- interrupts = <0 84 0>;
+ interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_ROTATOR>;
clock-names = "rotator";
iommus = <&sysmmu_rotator>;
@@ -642,7 +642,7 @@
gsc_0: video-scaler@13e00000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
- interrupts = <0 85 0>;
+ interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
power-domains = <&gsc_pd>;
@@ -652,7 +652,7 @@
gsc_1: video-scaler@13e10000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e10000 0x1000>;
- interrupts = <0 86 0>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_GSCL1>;
clock-names = "gscl";
power-domains = <&gsc_pd>;
@@ -662,7 +662,7 @@
jpeg_0: jpeg@11F50000 {
compatible = "samsung,exynos5420-jpeg";
reg = <0x11F50000 0x1000>;
- interrupts = <0 89 0>;
+ interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "jpeg";
clocks = <&clock CLK_JPEG>;
iommus = <&sysmmu_jpeg0>;
@@ -671,7 +671,7 @@
jpeg_1: jpeg@11F60000 {
compatible = "samsung,exynos5420-jpeg";
reg = <0x11F60000 0x1000>;
- interrupts = <0 168 0>;
+ interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "jpeg";
clocks = <&clock CLK_JPEG2>;
iommus = <&sysmmu_jpeg1>;
@@ -691,7 +691,7 @@
tmu_cpu0: tmu@10060000 {
compatible = "samsung,exynos5420-tmu";
reg = <0x10060000 0x100>;
- interrupts = <0 65 0>;
+ interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -700,7 +700,7 @@
tmu_cpu1: tmu@10064000 {
compatible = "samsung,exynos5420-tmu";
reg = <0x10064000 0x100>;
- interrupts = <0 183 0>;
+ interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>;
clock-names = "tmu_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -709,7 +709,7 @@
tmu_cpu2: tmu@10068000 {
compatible = "samsung,exynos5420-tmu-ext-triminfo";
reg = <0x10068000 0x100>, <0x1006c000 0x4>;
- interrupts = <0 184 0>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>, <&clock CLK_TMU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -718,7 +718,7 @@
tmu_cpu3: tmu@1006c000 {
compatible = "samsung,exynos5420-tmu-ext-triminfo";
reg = <0x1006c000 0x100>, <0x100a0000 0x4>;
- interrupts = <0 185 0>;
+ interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -727,7 +727,7 @@
tmu_gpu: tmu@100a0000 {
compatible = "samsung,exynos5420-tmu-ext-triminfo";
reg = <0x100a0000 0x100>, <0x10068000 0x4>;
- interrupts = <0 215 0>;
+ interrupts = <0 215 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
#include "exynos4412-tmu-sensor-conf.dtsi"
@@ -799,7 +799,7 @@
sysmmu_scaler1r: sysmmu@0x12890000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x12890000 0x1000>;
- interrupts = <0 186 0>;
+ interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "sysmmu", "master";
clocks = <&clock CLK_SMMU_MSCL1>, <&clock CLK_MSCL1>;
#iommu-cells = <0>;
@@ -808,7 +808,7 @@
sysmmu_scaler2r: sysmmu@0x128A0000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x128A0000 0x1000>;
- interrupts = <0 188 0>;
+ interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "sysmmu", "master";
clocks = <&clock CLK_SMMU_MSCL2>, <&clock CLK_MSCL2>;
#iommu-cells = <0>;
@@ -867,7 +867,7 @@
sysmmu_jpeg1: sysmmu@0x11F20000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x11F20000 0x1000>;
- interrupts = <0 169 0>;
+ interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "sysmmu", "master";
clocks = <&clock CLK_SMMU_JPEG2>, <&clock CLK_JPEG2>;
#iommu-cells = <0>;
@@ -1445,7 +1445,7 @@
};
&usbdrd_dwc3_1 {
- interrupts = <GIC_SPI 73 0>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
};
&usbdrd_phy1 {
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index 246d298557f5..05b9afdd6757 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -147,6 +147,11 @@
};
};
+&adc {
+ vdd-supply = <&ldo4_reg>;
+ status = "okay";
+};
+
&bus_wcore {
devfreq-events = <&nocp_mem0_0>, <&nocp_mem0_1>,
<&nocp_mem1_0>, <&nocp_mem1_1>;
@@ -293,6 +298,12 @@
regulator-max-microvolt = <1800000>;
};
+ ldo4_reg: LDO4 {
+ regulator-name = "vdd_adc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
ldo5_reg: LDO5 {
regulator-name = "vdd_ldo5";
regulator-min-microvolt = <1800000>;
@@ -499,7 +510,6 @@
&mmc_0 {
status = "okay";
mmc-pwrseq = <&emmc_pwrseq>;
- cd-gpios = <&gpc0 2 GPIO_ACTIVE_LOW>;
card-detect-delay = <200>;
samsung,dw-mshc-ciu-div = <3>;
samsung,dw-mshc-sdr-timing = <0 4>;
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
index e6bffd13cedd..2a2e570bbee6 100644
--- a/arch/arm/boot/dts/exynos5440.dtsi
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -10,6 +10,8 @@
*/
#include <dt-bindings/clock/exynos5440.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
compatible = "samsung,exynos5440", "samsung,exynos5";
@@ -41,7 +43,8 @@
<0x2E2000 0x1000>,
<0x2E4000 0x2000>,
<0x2E6000 0x2000>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
cpus {
@@ -72,26 +75,26 @@
arm-pmu {
compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
- interrupts = <0 52 4>,
- <0 53 4>,
- <0 54 4>,
- <0 55 4>;
+ interrupts = <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>;
};
timer {
compatible = "arm,cortex-a15-timer",
"arm,armv7-timer";
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>,
- <1 11 0xf08>,
- <1 10 0xf08>;
+ 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)>;
clock-frequency = <50000000>;
};
cpufreq@160000 {
compatible = "samsung,exynos5440-cpufreq";
reg = <0x160000 0x1000>;
- interrupts = <0 57 0>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
operating-points = <
/* KHz uV */
1500000 1100000
@@ -108,7 +111,7 @@
serial_0: serial@B0000 {
compatible = "samsung,exynos4210-uart";
reg = <0xB0000 0x1000>;
- interrupts = <0 2 0>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
clock-names = "uart", "clk_uart_baud0";
};
@@ -116,7 +119,7 @@
serial_1: serial@C0000 {
compatible = "samsung,exynos4210-uart";
reg = <0xC0000 0x1000>;
- interrupts = <0 3 0>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
clock-names = "uart", "clk_uart_baud0";
};
@@ -124,7 +127,7 @@
spi_0: spi@D0000 {
compatible = "samsung,exynos5440-spi";
reg = <0xD0000 0x100>;
- interrupts = <0 4 0>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
samsung,spi-src-clk = <0>;
@@ -136,8 +139,14 @@
pin_ctrl: pinctrl@E0000 {
compatible = "samsung,exynos5440-pinctrl";
reg = <0xE0000 0x1000>;
- interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>,
- <0 41 0>, <0 42 0>, <0 43 0>, <0 44 0>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <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>;
interrupt-controller;
#interrupt-cells = <2>;
#gpio-cells = <2>;
@@ -162,7 +171,7 @@
i2c@F0000 {
compatible = "samsung,exynos5440-i2c";
reg = <0xF0000 0x1000>;
- interrupts = <0 5 0>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_B_125>;
@@ -172,7 +181,7 @@
i2c@100000 {
compatible = "samsung,exynos5440-i2c";
reg = <0x100000 0x1000>;
- interrupts = <0 6 0>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clock CLK_B_125>;
@@ -182,16 +191,16 @@
watchdog@110000 {
compatible = "samsung,s3c2410-wdt";
reg = <0x110000 0x1000>;
- interrupts = <0 1 0>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>;
clock-names = "watchdog";
};
gmac: ethernet@00230000 {
- compatible = "snps,dwmac-3.70a";
+ compatible = "snps,dwmac-3.70a", "snps,dwmac";
reg = <0x00230000 0x8000>;
interrupt-parent = <&gic>;
- interrupts = <0 31 4>;
+ interrupts = <GIC_SPI 31 4>;
interrupt-names = "macirq";
phy-mode = "sgmii";
clocks = <&clock CLK_GMAC0>;
@@ -209,7 +218,8 @@
rtc@130000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x130000 0x1000>;
- interrupts = <0 17 0>, <0 16 0>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>;
clock-names = "rtc";
};
@@ -217,7 +227,7 @@
tmuctrl_0: tmuctrl@160118 {
compatible = "samsung,exynos5440-tmu";
reg = <0x160118 0x230>, <0x160368 0x10>;
- interrupts = <0 58 0>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>;
clock-names = "tmu_apbif";
#include "exynos5440-tmu-sensor-conf.dtsi"
@@ -226,7 +236,7 @@
tmuctrl_1: tmuctrl@16011C {
compatible = "samsung,exynos5440-tmu";
reg = <0x16011C 0x230>, <0x160368 0x10>;
- interrupts = <0 58 0>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>;
clock-names = "tmu_apbif";
#include "exynos5440-tmu-sensor-conf.dtsi"
@@ -235,7 +245,7 @@
tmuctrl_2: tmuctrl@160120 {
compatible = "samsung,exynos5440-tmu";
reg = <0x160120 0x230>, <0x160368 0x10>;
- interrupts = <0 58 0>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_B_125>;
clock-names = "tmu_apbif";
#include "exynos5440-tmu-sensor-conf.dtsi"
@@ -259,7 +269,7 @@
sata@210000 {
compatible = "snps,exynos5440-ahci";
reg = <0x210000 0x10000>;
- interrupts = <0 30 0>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_SATA>;
clock-names = "sata";
};
@@ -267,7 +277,7 @@
ohci@220000 {
compatible = "samsung,exynos5440-ohci";
reg = <0x220000 0x1000>;
- interrupts = <0 29 0>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB>;
clock-names = "usbhost";
};
@@ -275,7 +285,7 @@
ehci@221000 {
compatible = "samsung,exynos5440-ehci";
reg = <0x221000 0x1000>;
- interrupts = <0 29 0>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_USB>;
clock-names = "usbhost";
};
@@ -285,7 +295,9 @@
reg = <0x290000 0x1000
0x270000 0x1000
0x271000 0x40>;
- interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PR0_250_O>, <&clock CLK_PB0_250_O>;
clock-names = "pcie", "pcie_bus";
#address-cells = <3>;
@@ -306,7 +318,9 @@
reg = <0x2a0000 0x1000
0x272000 0x1000
0x271040 0x40>;
- interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PR1_250_O>, <&clock CLK_PB0_250_O>;
clock-names = "pcie", "pcie_bus";
#address-cells = <3>;
diff --git a/arch/arm/boot/dts/exynos54xx.dtsi b/arch/arm/boot/dts/exynos54xx.dtsi
index 9d31cdce1959..0389e8a10d0b 100644
--- a/arch/arm/boot/dts/exynos54xx.dtsi
+++ b/arch/arm/boot/dts/exynos54xx.dtsi
@@ -62,34 +62,34 @@
<1 &combiner 23 4>,
<2 &combiner 25 2>,
<3 &combiner 25 3>,
- <4 &gic 0 120 0>,
- <5 &gic 0 121 0>,
- <6 &gic 0 122 0>,
- <7 &gic 0 123 0>,
- <8 &gic 0 128 0>,
- <9 &gic 0 129 0>,
- <10 &gic 0 130 0>,
- <11 &gic 0 131 0>;
+ <4 &gic 0 120 IRQ_TYPE_LEVEL_HIGH>,
+ <5 &gic 0 121 IRQ_TYPE_LEVEL_HIGH>,
+ <6 &gic 0 122 IRQ_TYPE_LEVEL_HIGH>,
+ <7 &gic 0 123 IRQ_TYPE_LEVEL_HIGH>,
+ <8 &gic 0 128 IRQ_TYPE_LEVEL_HIGH>,
+ <9 &gic 0 129 IRQ_TYPE_LEVEL_HIGH>,
+ <10 &gic 0 130 IRQ_TYPE_LEVEL_HIGH>,
+ <11 &gic 0 131 IRQ_TYPE_LEVEL_HIGH>;
};
};
watchdog: watchdog@101d0000 {
compatible = "samsung,exynos5420-wdt";
reg = <0x101d0000 0x100>;
- interrupts = <0 42 0>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
};
sss: sss@10830000 {
compatible = "samsung,exynos4210-secss";
reg = <0x10830000 0x300>;
- interrupts = <0 112 0>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
};
/* i2c_0-3 are defined in exynos5.dtsi */
hsi2c_4: i2c@12ca0000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12ca0000 0x1000>;
- interrupts = <0 60 0>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -98,7 +98,7 @@
hsi2c_5: i2c@12cb0000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12cb0000 0x1000>;
- interrupts = <0 61 0>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -107,7 +107,7 @@
hsi2c_6: i2c@12cc0000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12cc0000 0x1000>;
- interrupts = <0 62 0>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -116,7 +116,7 @@
hsi2c_7: i2c@12cd0000 {
compatible = "samsung,exynos5250-hsi2c";
reg = <0x12cd0000 0x1000>;
- interrupts = <0 63 0>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -131,7 +131,7 @@
usbdrd_dwc3_0: dwc3@12000000 {
compatible = "snps,dwc3";
reg = <0x12000000 0x10000>;
- interrupts = <0 72 0>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usbdrd_phy0 0>, <&usbdrd_phy0 1>;
phy-names = "usb2-phy", "usb3-phy";
};
@@ -166,7 +166,7 @@
usbhost2: usb@12110000 {
compatible = "samsung,exynos4210-ehci";
reg = <0x12110000 0x100>;
- interrupts = <0 71 0>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
@@ -179,7 +179,7 @@
usbhost1: usb@12120000 {
compatible = "samsung,exynos4210-ohci";
reg = <0x12120000 0x100>;
- interrupts = <0 71 0>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 01f466816fea..f9ff7f07ae0c 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -665,6 +665,7 @@
status = "okay";
};
+/* eMMC flash */
&mmc_0 {
status = "okay";
num-slots = <1>;
@@ -683,6 +684,7 @@
bus-width = <8>;
};
+/* WiFi SDIO module */
&mmc_1 {
status = "okay";
num-slots = <1>;
@@ -702,6 +704,7 @@
vqmmc-supply = <&buck10_reg>;
};
+/* uSD card */
&mmc_2 {
status = "okay";
num-slots = <1>;
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
index c85d07e6db61..541d70094544 100644
--- a/arch/arm/boot/dts/hi3620.dtsi
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -11,10 +11,12 @@
* publishhed by the Free Software Foundation.
*/
-#include "skeleton.dtsi"
#include <dt-bindings/clock/hi3620-clock.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
serial0 = &uart0;
serial1 = &uart1;
@@ -537,6 +539,7 @@
reg = <0x803000 0x188>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
#gpio-range-cells = <3>;
ranges;
@@ -558,6 +561,7 @@
reg = <0x803800 0x2dc>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
ranges;
pinctrl-single,register-width = <32>;
diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi
index 4e9562f806a2..9d5fd5cfefa6 100644
--- a/arch/arm/boot/dts/hip01.dtsi
+++ b/arch/arm/boot/dts/hip01.dtsi
@@ -11,8 +11,6 @@
* published by the Free Software Foundation.
*/
-#include "skeleton.dtsi"
-
/ {
interrupt-parent = <&gic>;
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi
index 0da76c5ff6d7..c02e092fad8b 100644
--- a/arch/arm/boot/dts/hisi-x5hd2.dtsi
+++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi
@@ -7,10 +7,12 @@
* publishhed by the Free Software Foundation.
*/
-#include "skeleton.dtsi"
#include <dt-bindings/clock/hix5hd2-clock.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
serial0 = &uart0;
};
diff --git a/arch/arm/boot/dts/imx1.dtsi b/arch/arm/boot/dts/imx1.dtsi
index 22f5d1db5b31..b792eee3899b 100644
--- a/arch/arm/boot/dts/imx1.dtsi
+++ b/arch/arm/boot/dts/imx1.dtsi
@@ -9,7 +9,6 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx1-pinfunc.h"
#include <dt-bindings/clock/imx1-clock.h>
@@ -17,6 +16,9 @@
#include <dt-bindings/interrupt-controller/irq.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
gpio0 = &gpio1;
gpio1 = &gpio2;
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 440ee9a4a158..ac2a9da62b6c 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -9,10 +9,12 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx23-pinfunc.h"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
interrupt-parent = <&icoll>;
aliases {
@@ -464,7 +466,7 @@
reg = <0x80038000 0x2000>;
status = "disabled";
};
- };
+ };
apbx@80040000 {
compatible = "simple-bus";
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index af6af8741fe5..831d09a28155 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -9,10 +9,12 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx25-pinfunc.h"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index f818ea483aeb..9d8b5969ee3b 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -9,7 +9,6 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx27-pinfunc.h"
#include <dt-bindings/clock/imx27-clock.h>
@@ -18,6 +17,9 @@
#include <dt-bindings/interrupt-controller/irq.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
diff --git a/arch/arm/boot/dts/imx28-m28.dtsi b/arch/arm/boot/dts/imx28-m28.dtsi
index 214bb1506b53..a69856e41ba4 100644
--- a/arch/arm/boot/dts/imx28-m28.dtsi
+++ b/arch/arm/boot/dts/imx28-m28.dtsi
@@ -12,8 +12,8 @@
#include "imx28.dtsi"
/ {
- model = "DENX M28";
- compatible = "denx,m28", "fsl,imx28";
+ model = "Aries/DENX M28";
+ compatible = "aries,m28", "denx,m28", "fsl,imx28";
memory {
reg = <0x40000000 0x08000000>;
diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts
index 8d04e57039bc..dbfb8aab505f 100644
--- a/arch/arm/boot/dts/imx28-m28evk.dts
+++ b/arch/arm/boot/dts/imx28-m28evk.dts
@@ -13,8 +13,8 @@
#include "imx28-m28.dtsi"
/ {
- model = "DENX M28EVK";
- compatible = "denx,m28evk", "fsl,imx28";
+ model = "Aries/DENX M28EVK";
+ compatible = "aries,m28evk", "denx,m28evk", "fsl,imx28";
apb@80000000 {
apbh@80000000 {
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 0ad893bf5f43..3aabf65a6a52 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -10,10 +10,12 @@
*/
#include <dt-bindings/gpio/gpio.h>
-#include "skeleton.dtsi"
#include "imx28-pinfunc.h"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
interrupt-parent = <&icoll>;
aliases {
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi
index 1ce7ae94e7ad..685916e3d8a1 100644
--- a/arch/arm/boot/dts/imx31.dtsi
+++ b/arch/arm/boot/dts/imx31.dtsi
@@ -9,9 +9,10 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
-
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
serial0 = &uart1;
serial1 = &uart2;
@@ -118,13 +119,6 @@
interrupts = <19>;
clocks = <&clks 25>;
};
-
- clks: ccm@53f80000{
- compatible = "fsl,imx31-ccm";
- reg = <0x53f80000 0x4000>;
- interrupts = <0 31 0x04 0 53 0x04>;
- #clock-cells = <1>;
- };
};
aips@53f00000 { /* AIPS2 */
@@ -134,6 +128,13 @@
reg = <0x53f00000 0x100000>;
ranges;
+ clks: ccm@53f80000{
+ compatible = "fsl,imx31-ccm";
+ reg = <0x53f80000 0x4000>;
+ interrupts = <31>, <53>;
+ #clock-cells = <1>;
+ };
+
gpt: timer@53f90000 {
compatible = "fsl,imx31-gpt";
reg = <0x53f90000 0x4000>;
diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi
index f812d586c5ce..9f40e6229189 100644
--- a/arch/arm/boot/dts/imx35.dtsi
+++ b/arch/arm/boot/dts/imx35.dtsi
@@ -8,10 +8,12 @@
* Free Software Foundation.
*/
-#include "skeleton.dtsi"
#include "imx35-pinfunc.h"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
index 8fe8beeb68a4..fe0221e4cbf7 100644
--- a/arch/arm/boot/dts/imx50.dtsi
+++ b/arch/arm/boot/dts/imx50.dtsi
@@ -11,11 +11,13 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx50-pinfunc.h"
#include <dt-bindings/clock/imx5-clock.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
@@ -103,8 +105,8 @@
reg = <0x50004000 0x4000>;
interrupts = <1>;
clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC1_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -115,8 +117,8 @@
reg = <0x50008000 0x4000>;
interrupts = <2>;
clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC2_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -127,7 +129,7 @@
reg = <0x5000c000 0x4000>;
interrupts = <33>;
clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
- <&clks IMX5_CLK_UART3_PER_GATE>;
+ <&clks IMX5_CLK_UART3_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -139,7 +141,7 @@
reg = <0x50010000 0x4000>;
interrupts = <36>;
clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
- <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+ <&clks IMX5_CLK_ECSPI1_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -164,8 +166,8 @@
reg = <0x50020000 0x4000>;
interrupts = <3>;
clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC3_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -176,8 +178,8 @@
reg = <0x50024000 0x4000>;
interrupts = <4>;
clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC4_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -279,7 +281,7 @@
reg = <0x53fa0000 0x4000>;
interrupts = <39>;
clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
- <&clks IMX5_CLK_GPT_HF_GATE>;
+ <&clks IMX5_CLK_GPT_HF_GATE>;
clock-names = "ipg", "per";
};
@@ -298,7 +300,7 @@
compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
reg = <0x53fb4000 0x4000>;
clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
- <&clks IMX5_CLK_PWM1_HF_GATE>;
+ <&clks IMX5_CLK_PWM1_HF_GATE>;
clock-names = "ipg", "per";
interrupts = <61>;
};
@@ -308,7 +310,7 @@
compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
reg = <0x53fb8000 0x4000>;
clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
- <&clks IMX5_CLK_PWM2_HF_GATE>;
+ <&clks IMX5_CLK_PWM2_HF_GATE>;
clock-names = "ipg", "per";
interrupts = <94>;
};
@@ -318,7 +320,7 @@
reg = <0x53fbc000 0x4000>;
interrupts = <31>;
clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
- <&clks IMX5_CLK_UART1_PER_GATE>;
+ <&clks IMX5_CLK_UART1_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -328,7 +330,7 @@
reg = <0x53fc0000 0x4000>;
interrupts = <32>;
clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
- <&clks IMX5_CLK_UART2_PER_GATE>;
+ <&clks IMX5_CLK_UART2_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -383,7 +385,7 @@
reg = <0x53ff0000 0x4000>;
interrupts = <13>;
clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
- <&clks IMX5_CLK_UART4_PER_GATE>;
+ <&clks IMX5_CLK_UART4_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -401,7 +403,7 @@
reg = <0x63f90000 0x4000>;
interrupts = <86>;
clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
- <&clks IMX5_CLK_UART5_PER_GATE>;
+ <&clks IMX5_CLK_UART5_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -420,7 +422,7 @@
reg = <0x63fac000 0x4000>;
interrupts = <37>;
clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
- <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+ <&clks IMX5_CLK_ECSPI2_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -430,7 +432,7 @@
reg = <0x63fb0000 0x4000>;
interrupts = <6>;
clocks = <&clks IMX5_CLK_SDMA_GATE>,
- <&clks IMX5_CLK_SDMA_GATE>;
+ <&clks IMX5_CLK_SDMA_GATE>;
clock-names = "ipg", "ahb";
fsl,sdma-ram-script-name = "imx/sdma/sdma-imx50.bin";
};
@@ -442,7 +444,7 @@
reg = <0x63fc0000 0x4000>;
interrupts = <38>;
clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
- <&clks IMX5_CLK_CSPI_IPG_GATE>;
+ <&clks IMX5_CLK_CSPI_IPG_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -492,8 +494,8 @@
reg = <0x63fec000 0x4000>;
interrupts = <87>;
clocks = <&clks IMX5_CLK_FEC_GATE>,
- <&clks IMX5_CLK_FEC_GATE>,
- <&clks IMX5_CLK_FEC_GATE>;
+ <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>;
clock-names = "ipg", "ahb", "ptp";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index f46fe9bf0bcb..33526cade735 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -10,7 +10,6 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx51-pinfunc.h"
#include <dt-bindings/clock/imx5-clock.h>
#include <dt-bindings/gpio/gpio.h>
@@ -18,6 +17,9 @@
#include <dt-bindings/interrupt-controller/irq.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
@@ -130,8 +132,8 @@
reg = <0x40000000 0x20000000>;
interrupts = <11 10>;
clocks = <&clks IMX5_CLK_IPU_GATE>,
- <&clks IMX5_CLK_IPU_DI0_GATE>,
- <&clks IMX5_CLK_IPU_DI1_GATE>;
+ <&clks IMX5_CLK_IPU_DI0_GATE>,
+ <&clks IMX5_CLK_IPU_DI1_GATE>;
clock-names = "bus", "di0", "di1";
resets = <&src 2>;
@@ -169,8 +171,8 @@
reg = <0x70004000 0x4000>;
interrupts = <1>;
clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC1_PER_GATE>;
clock-names = "ipg", "ahb", "per";
status = "disabled";
};
@@ -180,8 +182,8 @@
reg = <0x70008000 0x4000>;
interrupts = <2>;
clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC2_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -192,7 +194,7 @@
reg = <0x7000c000 0x4000>;
interrupts = <33>;
clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
- <&clks IMX5_CLK_UART3_PER_GATE>;
+ <&clks IMX5_CLK_UART3_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -204,7 +206,7 @@
reg = <0x70010000 0x4000>;
interrupts = <36>;
clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
- <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+ <&clks IMX5_CLK_ECSPI1_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -229,8 +231,8 @@
reg = <0x70020000 0x4000>;
interrupts = <3>;
clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC3_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -241,8 +243,8 @@
reg = <0x70024000 0x4000>;
interrupts = <4>;
clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC4_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -364,7 +366,7 @@
reg = <0x73fa0000 0x4000>;
interrupts = <39>;
clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
- <&clks IMX5_CLK_GPT_HF_GATE>;
+ <&clks IMX5_CLK_GPT_HF_GATE>;
clock-names = "ipg", "per";
};
@@ -378,7 +380,7 @@
compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
reg = <0x73fb4000 0x4000>;
clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
- <&clks IMX5_CLK_PWM1_HF_GATE>;
+ <&clks IMX5_CLK_PWM1_HF_GATE>;
clock-names = "ipg", "per";
interrupts = <61>;
};
@@ -388,7 +390,7 @@
compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
reg = <0x73fb8000 0x4000>;
clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
- <&clks IMX5_CLK_PWM2_HF_GATE>;
+ <&clks IMX5_CLK_PWM2_HF_GATE>;
clock-names = "ipg", "per";
interrupts = <94>;
};
@@ -398,7 +400,7 @@
reg = <0x73fbc000 0x4000>;
interrupts = <31>;
clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
- <&clks IMX5_CLK_UART1_PER_GATE>;
+ <&clks IMX5_CLK_UART1_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -408,7 +410,7 @@
reg = <0x73fc0000 0x4000>;
interrupts = <32>;
clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
- <&clks IMX5_CLK_UART2_PER_GATE>;
+ <&clks IMX5_CLK_UART2_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -456,7 +458,7 @@
reg = <0x83fac000 0x4000>;
interrupts = <37>;
clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
- <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+ <&clks IMX5_CLK_ECSPI2_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -466,7 +468,7 @@
reg = <0x83fb0000 0x4000>;
interrupts = <6>;
clocks = <&clks IMX5_CLK_SDMA_GATE>,
- <&clks IMX5_CLK_SDMA_GATE>;
+ <&clks IMX5_CLK_SDMA_GATE>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
@@ -479,7 +481,7 @@
reg = <0x83fc0000 0x4000>;
interrupts = <38>;
clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
- <&clks IMX5_CLK_CSPI_IPG_GATE>;
+ <&clks IMX5_CLK_CSPI_IPG_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -582,8 +584,8 @@
reg = <0x83fec000 0x4000>;
interrupts = <87>;
clocks = <&clks IMX5_CLK_FEC_GATE>,
- <&clks IMX5_CLK_FEC_GATE>,
- <&clks IMX5_CLK_FEC_GATE>;
+ <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>;
clock-names = "ipg", "ahb", "ptp";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx53-m53.dtsi b/arch/arm/boot/dts/imx53-m53.dtsi
index d259f57bfd98..ec390aa562c3 100644
--- a/arch/arm/boot/dts/imx53-m53.dtsi
+++ b/arch/arm/boot/dts/imx53-m53.dtsi
@@ -12,8 +12,8 @@
#include "imx53.dtsi"
/ {
- model = "DENX M53";
- compatible = "denx,imx53-m53", "fsl,imx53";
+ model = "Aries/DENX M53";
+ compatible = "aries,imx53-m53", "denx,imx53-m53", "fsl,imx53";
memory {
reg = <0x70000000 0x20000000>,
diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts
index dcee1e0f968f..4347a321c782 100644
--- a/arch/arm/boot/dts/imx53-m53evk.dts
+++ b/arch/arm/boot/dts/imx53-m53evk.dts
@@ -13,8 +13,8 @@
#include "imx53-m53.dtsi"
/ {
- model = "DENX M53EVK";
- compatible = "denx,imx53-m53evk", "fsl,imx53";
+ model = "Aries/DENX M53EVK";
+ compatible = "aries,imx53-m53evk", "denx,imx53-m53evk", "fsl,imx53";
display1: display@di1 {
compatible = "fsl,imx-parallel-display";
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 0777b41cdfe8..ca51dc03e327 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -10,7 +10,6 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-#include "skeleton.dtsi"
#include "imx53-pinfunc.h"
#include <dt-bindings/clock/imx5-clock.h>
#include <dt-bindings/gpio/gpio.h>
@@ -18,6 +17,9 @@
#include <dt-bindings/interrupt-controller/irq.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
@@ -131,8 +133,8 @@
reg = <0x18000000 0x08000000>;
interrupts = <11 10>;
clocks = <&clks IMX5_CLK_IPU_GATE>,
- <&clks IMX5_CLK_IPU_DI0_GATE>,
- <&clks IMX5_CLK_IPU_DI1_GATE>;
+ <&clks IMX5_CLK_IPU_DI0_GATE>,
+ <&clks IMX5_CLK_IPU_DI1_GATE>;
clock-names = "bus", "di0", "di1";
resets = <&src 2>;
@@ -199,8 +201,8 @@
reg = <0x50004000 0x4000>;
interrupts = <1>;
clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC1_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -211,8 +213,8 @@
reg = <0x50008000 0x4000>;
interrupts = <2>;
clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC2_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -223,7 +225,7 @@
reg = <0x5000c000 0x4000>;
interrupts = <33>;
clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
- <&clks IMX5_CLK_UART3_PER_GATE>;
+ <&clks IMX5_CLK_UART3_PER_GATE>;
clock-names = "ipg", "per";
dmas = <&sdma 42 4 0>, <&sdma 43 4 0>;
dma-names = "rx", "tx";
@@ -237,7 +239,7 @@
reg = <0x50010000 0x4000>;
interrupts = <36>;
clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
- <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+ <&clks IMX5_CLK_ECSPI1_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -264,8 +266,8 @@
reg = <0x50020000 0x4000>;
interrupts = <3>;
clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC3_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -276,8 +278,8 @@
reg = <0x50024000 0x4000>;
interrupts = <4>;
clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
- <&clks IMX5_CLK_DUMMY>,
- <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+ <&clks IMX5_CLK_DUMMY>,
+ <&clks IMX5_CLK_ESDHC4_PER_GATE>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
@@ -419,7 +421,7 @@
reg = <0x53fa0000 0x4000>;
interrupts = <39>;
clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
- <&clks IMX5_CLK_GPT_HF_GATE>;
+ <&clks IMX5_CLK_GPT_HF_GATE>;
clock-names = "ipg", "per";
};
@@ -440,11 +442,11 @@
reg = <0x53fa8008 0x4>;
gpr = <&gpr>;
clocks = <&clks IMX5_CLK_LDB_DI0_SEL>,
- <&clks IMX5_CLK_LDB_DI1_SEL>,
- <&clks IMX5_CLK_IPU_DI0_SEL>,
- <&clks IMX5_CLK_IPU_DI1_SEL>,
- <&clks IMX5_CLK_LDB_DI0_GATE>,
- <&clks IMX5_CLK_LDB_DI1_GATE>;
+ <&clks IMX5_CLK_LDB_DI1_SEL>,
+ <&clks IMX5_CLK_IPU_DI0_SEL>,
+ <&clks IMX5_CLK_IPU_DI1_SEL>,
+ <&clks IMX5_CLK_LDB_DI0_GATE>,
+ <&clks IMX5_CLK_LDB_DI1_GATE>;
clock-names = "di0_pll", "di1_pll",
"di0_sel", "di1_sel",
"di0", "di1";
@@ -486,7 +488,7 @@
compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
reg = <0x53fb4000 0x4000>;
clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
- <&clks IMX5_CLK_PWM1_HF_GATE>;
+ <&clks IMX5_CLK_PWM1_HF_GATE>;
clock-names = "ipg", "per";
interrupts = <61>;
};
@@ -496,7 +498,7 @@
compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
reg = <0x53fb8000 0x4000>;
clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
- <&clks IMX5_CLK_PWM2_HF_GATE>;
+ <&clks IMX5_CLK_PWM2_HF_GATE>;
clock-names = "ipg", "per";
interrupts = <94>;
};
@@ -506,7 +508,7 @@
reg = <0x53fbc000 0x4000>;
interrupts = <31>;
clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
- <&clks IMX5_CLK_UART1_PER_GATE>;
+ <&clks IMX5_CLK_UART1_PER_GATE>;
clock-names = "ipg", "per";
dmas = <&sdma 18 4 0>, <&sdma 19 4 0>;
dma-names = "rx", "tx";
@@ -518,7 +520,7 @@
reg = <0x53fc0000 0x4000>;
interrupts = <32>;
clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
- <&clks IMX5_CLK_UART2_PER_GATE>;
+ <&clks IMX5_CLK_UART2_PER_GATE>;
clock-names = "ipg", "per";
dmas = <&sdma 12 4 0>, <&sdma 13 4 0>;
dma-names = "rx", "tx";
@@ -530,7 +532,7 @@
reg = <0x53fc8000 0x4000>;
interrupts = <82>;
clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>,
- <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
+ <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -540,7 +542,7 @@
reg = <0x53fcc000 0x4000>;
interrupts = <83>;
clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>,
- <&clks IMX5_CLK_CAN2_SERIAL_GATE>;
+ <&clks IMX5_CLK_CAN2_SERIAL_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -603,7 +605,7 @@
reg = <0x53ff0000 0x4000>;
interrupts = <13>;
clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
- <&clks IMX5_CLK_UART4_PER_GATE>;
+ <&clks IMX5_CLK_UART4_PER_GATE>;
clock-names = "ipg", "per";
dmas = <&sdma 2 4 0>, <&sdma 3 4 0>;
dma-names = "rx", "tx";
@@ -635,7 +637,7 @@
reg = <0x63f90000 0x4000>;
interrupts = <86>;
clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
- <&clks IMX5_CLK_UART5_PER_GATE>;
+ <&clks IMX5_CLK_UART5_PER_GATE>;
clock-names = "ipg", "per";
dmas = <&sdma 16 4 0>, <&sdma 17 4 0>;
dma-names = "rx", "tx";
@@ -656,7 +658,7 @@
reg = <0x63fac000 0x4000>;
interrupts = <37>;
clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
- <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+ <&clks IMX5_CLK_ECSPI2_PER_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -666,7 +668,7 @@
reg = <0x63fb0000 0x4000>;
interrupts = <6>;
clocks = <&clks IMX5_CLK_SDMA_GATE>,
- <&clks IMX5_CLK_SDMA_GATE>;
+ <&clks IMX5_CLK_SDMA_GATE>;
clock-names = "ipg", "ahb";
#dma-cells = <3>;
fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
@@ -679,7 +681,7 @@
reg = <0x63fc0000 0x4000>;
interrupts = <38>;
clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
- <&clks IMX5_CLK_CSPI_IPG_GATE>;
+ <&clks IMX5_CLK_CSPI_IPG_GATE>;
clock-names = "ipg", "per";
status = "disabled";
};
@@ -755,8 +757,8 @@
reg = <0x63fec000 0x4000>;
interrupts = <87>;
clocks = <&clks IMX5_CLK_FEC_GATE>,
- <&clks IMX5_CLK_FEC_GATE>,
- <&clks IMX5_CLK_FEC_GATE>;
+ <&clks IMX5_CLK_FEC_GATE>,
+ <&clks IMX5_CLK_FEC_GATE>;
clock-names = "ipg", "ahb", "ptp";
status = "disabled";
};
@@ -766,7 +768,7 @@
reg = <0x63ff0000 0x1000>;
interrupts = <92>;
clocks = <&clks IMX5_CLK_TVE_GATE>,
- <&clks IMX5_CLK_IPU_DI1_SEL>;
+ <&clks IMX5_CLK_IPU_DI1_SEL>;
clock-names = "tve", "di_sel";
status = "disabled";
@@ -782,7 +784,7 @@
reg = <0x63ff4000 0x1000>;
interrupts = <9>;
clocks = <&clks IMX5_CLK_VPU_REFERENCE_GATE>,
- <&clks IMX5_CLK_VPU_GATE>;
+ <&clks IMX5_CLK_VPU_GATE>;
clock-names = "per", "ahb";
resets = <&src 1>;
iram = <&ocram>;
@@ -793,7 +795,7 @@
reg = <0x63ff8000 0x4000>;
interrupts = <19 20>;
clocks = <&clks IMX5_CLK_SAHARA_IPG_GATE>,
- <&clks IMX5_CLK_SAHARA_IPG_GATE>;
+ <&clks IMX5_CLK_SAHARA_IPG_GATE>;
clock-names = "ipg", "ahb";
};
};
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
new file mode 100644
index 000000000000..e0c21727866d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2014-2016 Toradex AG
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro 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
+ * 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 <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "imx6dl.dtsi"
+#include "imx6qdl-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri iMX6DL/S on Colibri Evaluation Board V3";
+ compatible = "toradex,colibri_imx6dl-eval-v3", "toradex,colibri_imx6dl",
+ "fsl,imx6dl";
+
+ aliases {
+ i2c0 = &i2c2;
+ i2c1 = &i2c3;
+ };
+
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ clocks {
+ /* Fixed crystal dedicated to mcp251x */
+ clk16m: clk@1 {
+ compatible = "fixed-clock";
+ reg = <1>;
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "clk16m";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ label = "Wake-Up";
+ gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; /* SODIMM 45 */
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ wakeup-source;
+ };
+ };
+
+ lcd_display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu1_lcdif>;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+
+ lcd_display_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lcd_display_out: endpoint {
+ remote-endpoint = <&lcd_panel_in>;
+ };
+ };
+ };
+
+ panel: panel {
+ /*
+ * edt,et057090dhu: EDT 5.7" LCD TFT
+ * edt,et070080dh6: EDT 7.0" LCD TFT
+ */
+ compatible = "edt,et057090dhu";
+ backlight = <&backlight>;
+
+ port {
+ lcd_panel_in: endpoint {
+ remote-endpoint = <&lcd_display_out>;
+ };
+ };
+ };
+};
+
+&backlight {
+ brightness-levels = <0 127 191 223 239 247 251 255>;
+ default-brightness-level = <1>;
+ status = "okay";
+};
+
+/* Colibri SSP */
+&ecspi4 {
+ status = "okay";
+
+ mcp251x0: mcp251x@1 {
+ compatible = "microchip,mcp2515";
+ reg = <0>;
+ clocks = <&clk16m>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 0x2>;
+ spi-max-frequency = <10000000>;
+ status = "okay";
+ };
+};
+
+&hdmi {
+ status = "okay";
+};
+
+/*
+ * Colibri I2C: I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier board)
+ */
+&i2c3 {
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t00";
+ reg = <0x68>;
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&lcd_display_in>;
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+};
+
+/* Colibri MMC */
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc_cd>;
+ cd-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; /* MMCD */
+ status = "okay";
+};
+
+&weim {
+ status = "okay";
+
+ /* weim memory map: 32MB on CS0, 32MB on CS1, 32MB on CS2 */
+ ranges = <0 0 0x08000000 0x02000000
+ 1 0 0x0a000000 0x02000000
+ 2 0 0x0c000000 0x02000000>;
+
+ /* SRAM on Colibri nEXT_CS0 */
+ sram@0,0 {
+ compatible = "cypress,cy7c1019dv33-10zsxi, mtd-ram";
+ reg = <0 0 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00010081 0x00000000 0x04000000
+ 0x00000000 0x04000040 0x00000000>;
+ };
+
+ /* SRAM on Colibri nEXT_CS1 */
+ sram@1,0 {
+ compatible = "cypress,cy7c1019dv33-10zsxi, mtd-ram";
+ reg = <1 0 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ fsl,weim-cs-timing = <0x00010081 0x00000000 0x04000000
+ 0x00000000 0x04000040 0x00000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6dl-icore.dts b/arch/arm/boot/dts/imx6dl-icore.dts
new file mode 100644
index 000000000000..aec332c14af1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-icore.dts
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Amarula Solutions B.V.
+ * Copyright (C) 2016 Engicam S.r.l.
+ *
+ * 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 "imx6dl.dtsi"
+#include "imx6qdl-icore.dtsi"
+
+/ {
+ model = "Engicam i.CoreM6 DualLite/Solo Starter Kit";
+ compatible = "engicam,imx6-icore", "fsl,imx6dl";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&can2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
index 75d73437adf7..2cb72824e800 100644
--- a/arch/arm/boot/dts/imx6dl-riotboard.dts
+++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
@@ -390,7 +390,7 @@
MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 /* AR8035 pin strapping: MODE#3: pull up */
MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0 /* AR8035 pin strapping: MODE#0: pull down */
MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 /* GPIO16 -> AR8035 25MHz */
- MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x130b0 /* RGMII_nRST */
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x130b0 /* RGMII_nRST */
MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x180b0 /* AR8035 interrupt */
MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
>;
diff --git a/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts b/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
index 063fe7510da5..aac42ac465b6 100644
--- a/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
+++ b/arch/arm/boot/dts/imx6dl-tx6dl-comtft.dts
@@ -105,7 +105,7 @@
pixelclk-active = <1>;
};
};
- };
+ };
};
&can1 {
diff --git a/arch/arm/boot/dts/imx6dl-tx6u-801x.dts b/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
index b7a72840b7f0..d1f1298ec55a 100644
--- a/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
+++ b/arch/arm/boot/dts/imx6dl-tx6u-801x.dts
@@ -199,7 +199,7 @@
pixelclk-active = <0>;
};
};
- };
+ };
};
&ipu1_di0_disp0 {
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 207b85b91ada..0ea75f7b6039 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -147,28 +147,6 @@
gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
};
};
-
- pwmleds {
- compatible = "pwm-leds";
-
- ledpwm1 {
- label = "PWM1";
- pwms = <&pwm1 0 50000>;
- max-brightness = <255>;
- };
-
- ledpwm2 {
- label = "PWM2";
- pwms = <&pwm2 0 50000>;
- max-brightness = <255>;
- };
-
- ledpwm3 {
- label = "PWM3";
- pwms = <&pwm3 0 50000>;
- max-brightness = <255>;
- };
- };
};
&backlight {
diff --git a/arch/arm/boot/dts/imx6q-b650v3.dts b/arch/arm/boot/dts/imx6q-b650v3.dts
index d85388725426..1dcaee23ed9c 100644
--- a/arch/arm/boot/dts/imx6q-b650v3.dts
+++ b/arch/arm/boot/dts/imx6q-b650v3.dts
@@ -98,3 +98,9 @@
line-name = "PCA9539-P05";
};
};
+
+&usbphy1 {
+ fsl,tx-cal-45-dn-ohms = <55>;
+ fsl,tx-cal-45-dp-ohms = <55>;
+ fsl,tx-d-cal = <100>;
+};
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
index 59bc5a4dce17..a150bca84daa 100644
--- a/arch/arm/boot/dts/imx6q-cm-fx6.dts
+++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts
@@ -183,7 +183,6 @@
MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
- MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
>;
};
diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts
index 6de21ff47c3a..7c7c1a855ece 100644
--- a/arch/arm/boot/dts/imx6q-evi.dts
+++ b/arch/arm/boot/dts/imx6q-evi.dts
@@ -232,10 +232,7 @@
};
&weim {
- #address-cells = <2>;
- #size-cells = <1>;
ranges = <0 0 0x08000000 0x08000000>;
- fsl,weim-cs-gpr = <&gpr>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_weimfpga &pinctrl_weimcs>;
status = "okay";
diff --git a/arch/arm/boot/dts/imx6q-icore.dts b/arch/arm/boot/dts/imx6q-icore.dts
new file mode 100644
index 000000000000..025f54350c28
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-icore.dts
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Amarula Solutions B.V.
+ * Copyright (C) 2016 Engicam S.r.l.
+ *
+ * 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 "imx6q.dtsi"
+#include "imx6qdl-icore.dtsi"
+
+/ {
+ model = "Engicam i.CoreM6 Quad/Dual Starter Kit";
+ compatible = "engicam,imx6-icore", "fsl,imx6q";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&can2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6_som2.dts b/arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
new file mode 100644
index 000000000000..cf4feefe02c5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Boundary Devices, 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
+ * 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 "imx6q.dtsi"
+#include "imx6qdl-nitrogen6_som2.dtsi"
+
+/ {
+ model = "Boundary Devices i.MX6 Quad Nitrogen6_SOM2 Board";
+ compatible = "boundary,imx6q-nitrogen6_som2", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-novena.dts b/arch/arm/boot/dts/imx6q-novena.dts
index 1723e89e3acc..758bca96786f 100644
--- a/arch/arm/boot/dts/imx6q-novena.dts
+++ b/arch/arm/boot/dts/imx6q-novena.dts
@@ -451,6 +451,10 @@
status = "okay";
};
+&pwm1 {
+ status = "okay";
+};
+
&sata {
target-supply = <&reg_sata>;
fsl,transmit-level-mV = <1025>;
diff --git a/arch/arm/boot/dts/imx6q-phytec-pbab01.dts b/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
index c139ac0ebe15..1f4771304da8 100644
--- a/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
+++ b/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
@@ -23,5 +23,5 @@
};
&sata {
- status = "okay";
+ status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts b/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
index 65e95ae7509a..71746edc2ee9 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1010-comtft.dts
@@ -105,7 +105,7 @@
pixelclk-active = <1>;
};
};
- };
+ };
};
&can1 {
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1010.dts b/arch/arm/boot/dts/imx6q-tx6q-1010.dts
index 20cd0e7b3e21..f9cd21a41a79 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1010.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1010.dts
@@ -199,7 +199,7 @@
pixelclk-active = <0>;
};
};
- };
+ };
};
&ipu1_di0_disp0 {
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts b/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
index 9ed243b704ff..959ff3fb7304 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1020-comtft.dts
@@ -105,7 +105,7 @@
pixelclk-active = <1>;
};
};
- };
+ };
};
&can1 {
diff --git a/arch/arm/boot/dts/imx6q-tx6q-1020.dts b/arch/arm/boot/dts/imx6q-tx6q-1020.dts
index 347b531d3763..b49133d25d80 100644
--- a/arch/arm/boot/dts/imx6q-tx6q-1020.dts
+++ b/arch/arm/boot/dts/imx6q-tx6q-1020.dts
@@ -199,7 +199,7 @@
pixelclk-active = <0>;
};
};
- };
+ };
};
&ds1339 {
diff --git a/arch/arm/boot/dts/imx6q-utilite-pro.dts b/arch/arm/boot/dts/imx6q-utilite-pro.dts
index 61990630a748..22009947cebc 100644
--- a/arch/arm/boot/dts/imx6q-utilite-pro.dts
+++ b/arch/arm/boot/dts/imx6q-utilite-pro.dts
@@ -68,7 +68,41 @@
label = "Power Button";
gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
- gpio-key,wakeup;
+ wakeup-source;
+ };
+ };
+
+ i2cmux {
+ compatible = "i2c-mux-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1mux>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mux-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ i2c-parent = <&i2c1>;
+
+ i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@50 {
+ compatible = "at24,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ em3027: rtc@56 {
+ compatible = "emmicro,em3027";
+ reg = <0x56>;
+ };
+ };
+
+ i2c_dvi_ddc: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
};
@@ -82,17 +116,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
-
- eeprom@50 {
- compatible = "at24,24c02";
- reg = <0x50>;
- pagesize = <16>;
- };
-
- em3027: rtc@56 {
- compatible = "emmicro,em3027";
- reg = <0x56>;
- };
};
&i2c2 {
@@ -115,6 +138,12 @@
>;
};
+ pinctrl_i2c1mux: i2c1muxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+
pinctrl_i2c2: i2c2grp {
fsl,pins = <
MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 99e323b57261..8c8a049eb3d0 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -49,7 +49,10 @@
backlight: backlight {
compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_bl_on>;
pwms = <&pwm4 0 5000000>;
+ enable-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
@@ -620,6 +623,12 @@
>;
};
+ pinctrl_gpio_bl_on: gpioblon {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0
+ >;
+ };
+
pinctrl_gpio_keys: gpio1io04grp {
fsl,pins = <
/* Power button */
diff --git a/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi b/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi
index edbce222c782..5e7792d6bf58 100644
--- a/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi
@@ -347,13 +347,13 @@
fsl,pins = <
MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x100b1
MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x100b1
- MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x100b1
- MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x100b1
- MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x100b1
- MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x100b1
- MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x100b1
- MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x100b1
- MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x100b1
+ MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x100b1
+ MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x100b1
+ MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x100b1
+ MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x100b1
+ MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x100b1
+ MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x100b1
+ MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x100b1
>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
new file mode 100644
index 000000000000..e6faa653f91a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -0,0 +1,890 @@
+/*
+ * Copyright 2014-2016 Toradex AG
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro 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
+ * 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/gpio/gpio.h>
+
+/ {
+ model = "Toradex Colibri iMX6DL/S Module";
+ compatible = "toradex,colibri_imx6dl", "fsl,imx6dl";
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_bl_on>;
+ pwms = <&pwm3 0 5000000>;
+ enable-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* Colibri BL_ON */
+ status = "disabled";
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ 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_usb_host_vbus: regulator-usb-host-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_regulator_usbh_pwr>;
+ regulator-name = "usb_host_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>; /* USBH_PEN */
+ status = "disabled";
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-sgtl5000";
+ model = "imx6dl-colibri-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "Headphone Jack", "HP_OUT",
+ "LINE_IN", "Line In Jack",
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias";
+ mux-int-port = <1>;
+ mux-ext-port = <5>;
+ };
+
+ /* Optional S/PDIF in on SODIMM 88 and out on SODIMM 90, 137 or 168 */
+ sound_spdif: sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif>;
+ spdif-in;
+ spdif-out;
+ status = "disabled";
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux &pinctrl_mic_gnd>;
+ status = "okay";
+};
+
+/* Optional on SODIMM 55/63 */
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
+/* Optional on SODIMM 178/188 */
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "disabled";
+};
+
+/* Colibri SSP */
+&ecspi4 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi4>;
+ status = "disabled";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rmii";
+ status = "okay";
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_ddc>;
+ status = "disabled";
+};
+
+/*
+ * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and
+ * touch screen controller
+ */
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1ab {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw1c_reg: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw3a_reg: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ swbst_reg: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ 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: unused */
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vgen3: unused */
+
+ vgen4_reg: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ /* STMPE811 touch screen controller */
+ stmpe811@41 {
+ compatible = "st,stmpe811";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touch_int>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x41>;
+ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&gpio6>;
+ interrupt-controller;
+ id = <0>;
+ blocks = <0x5>;
+ irq-trigger = <0x1>;
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ reg = <0>;
+ /* 3.25 MHz ADC clock speed */
+ st,adc-freq = <1>;
+ /* 8 sample average control */
+ st,ave-ctrl = <3>;
+ /* 7 length fractional part in z */
+ st,fraction-z = <7>;
+ /*
+ * 50 mA typical 80 mA max touchscreen drivers
+ * current limit value
+ */
+ st,i-drive = <1>;
+ /* 12-bit ADC */
+ st,mod-12b = <1>;
+ /* internal ADC reference */
+ st,ref-sel = <0>;
+ /* ADC converstion time: 80 clocks */
+ st,sample-time = <4>;
+ /* 1 ms panel driver settling time */
+ st,settling = <3>;
+ /* 5 ms touch detect interrupt delay */
+ st,touch-det-delay = <5>;
+ };
+ };
+};
+
+/*
+ * I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier board)
+ */
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "recovery";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_recovery>;
+ scl-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+};
+
+/* Colibri PWM<B> */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "disabled";
+};
+
+/* Colibri PWM<D> */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ status = "disabled";
+};
+
+/* Colibri PWM<A> */
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "disabled";
+};
+
+/* Colibri PWM<C> */
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "disabled";
+};
+
+/* Optional S/PDIF out on SODIMM 137 */
+&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif>;
+ status = "disabled";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+/* Colibri UART_A */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_dte &pinctrl_uart1_ctrl>;
+ fsl,dte-mode;
+ uart-has-rtscts;
+ status = "disabled";
+};
+
+/* Colibri UART_B */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_dte>;
+ fsl,dte-mode;
+ uart-has-rtscts;
+ status = "disabled";
+};
+
+/* Colibri UART_C */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3_dte>;
+ fsl,dte-mode;
+ status = "disabled";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ disable-over-current;
+ dr_mode = "peripheral";
+ status = "disabled";
+};
+
+/* Colibri MMC */
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ vqmmc-supply = <&reg_3p3v>;
+ bus-width = <4>;
+ voltage-ranges = <3300 3300>;
+ status = "disabled";
+};
+
+/* eMMC */
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ vqmmc-supply = <&reg_3p3v>;
+ bus-width = <8>;
+ voltage-ranges = <3300 3300>;
+ non-removable;
+ status = "okay";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim_sram &pinctrl_weim_cs0
+ &pinctrl_weim_cs1 &pinctrl_weim_cs2
+ &pinctrl_weim_rdnwr &pinctrl_weim_npwe>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_audmux: audmuxgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0
+ MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x130b0
+ MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_KEY_ROW1__AUD5_RXD 0x130b0
+ /* SGTL5000 sys_mclk */
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000b0
+ >;
+ };
+
+ pinctrl_cam_mclk: cammclkgrp {
+ fsl,pins = <
+ /* Parallel Camera CAM sys_mclk */
+ MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x00b0
+ >;
+ };
+
+ pinctrl_ecspi4: ecspi4grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1
+ MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x100b1
+ /* SPI CS */
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x000b1
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK ((1<<30) | 0x1b0b0)
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
+ MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0
+ MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpio_bl_on: gpioblon {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpio_keys: gpiokeys {
+ fsl,pins = <
+ /* Power button */
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0
+ >;
+ };
+
+ pinctrl_hdmi_ddc: hdmiddcgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3_recovery: i2c3recoverygrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x4001b8b1
+ MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x4001b8b1
+ >;
+ };
+
+ pinctrl_ipu1_csi0: ipu1csi0grp { /* Parallel Camera */
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0xb0b1
+ MX6QDL_PAD_EIM_A18__IPU1_CSI1_DATA13 0xb0b1
+ MX6QDL_PAD_EIM_A19__IPU1_CSI1_DATA14 0xb0b1
+ MX6QDL_PAD_EIM_A20__IPU1_CSI1_DATA15 0xb0b1
+ MX6QDL_PAD_EIM_A21__IPU1_CSI1_DATA16 0xb0b1
+ MX6QDL_PAD_EIM_A22__IPU1_CSI1_DATA17 0xb0b1
+ MX6QDL_PAD_EIM_A23__IPU1_CSI1_DATA18 0xb0b1
+ MX6QDL_PAD_EIM_A24__IPU1_CSI1_DATA19 0xb0b1
+ MX6QDL_PAD_EIM_D17__IPU1_CSI1_PIXCLK 0xb0b1
+ MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0xb0b1
+ MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0xb0b1
+ /* Disable PWM pins on camera interface */
+ MX6QDL_PAD_SD4_DAT1__GPIO2_IO09 0x40
+ MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x40
+ >;
+ };
+
+ pinctrl_ipu1_lcdif: ipu1lcdifgrp {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0xa1
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0xa1
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0xa1
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0xa1
+ MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0xa1
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0xa1
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0xa1
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0xa1
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0xa1
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0xa1
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0xa1
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0xa1
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0xa1
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0xa1
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0xa1
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0xa1
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0xa1
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0xa1
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0xa1
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0xa1
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0xa1
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0xa1
+ >;
+ };
+
+ pinctrl_mic_gnd: gpiomicgnd {
+ fsl,pins = <
+ /* Controls Mic GND, PU or '1' pull Mic GND to GND */
+ MX6QDL_PAD_RGMII_TD1__GPIO6_IO21 0x1b0b0
+ >;
+ };
+
+ pinctrl_mmc_cd: gpiommccd {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x80000000
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__PWM2_OUT 0x1b0b1
+ MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x00040
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x00040
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_regulator_usbh_pwr: gpioregusbhpwrgrp {
+ fsl,pins = <
+ /* USBH_EN */
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x0f058
+ >;
+ };
+
+ pinctrl_spdif: spdifgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
+ >;
+ };
+
+ pinctrl_touch_int: gpiotouchintgrp {
+ fsl,pins = <
+ /* STMPE811 interrupt */
+ MX6QDL_PAD_RGMII_TD0__GPIO6_IO20 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart1_dce: uart1dcegrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ /* DTE mode */
+ pinctrl_uart1_dte: uart1dtegrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_RX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT11__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D19__UART1_RTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D20__UART1_CTS_B 0x1b0b1
+ >;
+ };
+
+ /* Additional DTR, DSR, DCD */
+ pinctrl_uart1_ctrl: uart1ctrlgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D23__UART1_DCD_B 0x1b0b0
+ MX6QDL_PAD_EIM_D24__UART1_DTR_B 0x1b0b0
+ MX6QDL_PAD_EIM_D25__UART1_DSR_B 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart2_dte: uart2dtegrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT4__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT7__UART2_RX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT6__UART2_RTS_B 0x1b0b1
+ MX6QDL_PAD_SD4_DAT5__UART2_CTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3_dte: uart3dtegrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CLK__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_CMD__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbc_det: usbcdetgrp {
+ fsl,pins = <
+ /* USBC_DET */
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
+ /* USBC_DET_EN */
+ MX6QDL_PAD_RGMII_TX_CTL__GPIO6_IO26 0x0f058
+ /* USBC_DET_OVERWRITE */
+ MX6QDL_PAD_RGMII_RXC__GPIO6_IO30 0x0f058
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ /* eMMC reset */
+ MX6QDL_PAD_SD3_RST__SD3_RESET 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3100mhzgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
+ /* eMMC reset */
+ MX6QDL_PAD_SD3_RST__SD3_RESET 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3200mhzgrp {
+ 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
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
+ /* eMMC reset */
+ MX6QDL_PAD_SD3_RST__SD3_RESET 0x170f9
+ >;
+ };
+
+ pinctrl_weim_cs0: weimcs0grp {
+ fsl,pins = <
+ /* nEXT_CS0 */
+ MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_cs1: weimcs1grp {
+ fsl,pins = <
+ /* nEXT_CS1 */
+ MX6QDL_PAD_EIM_CS1__EIM_CS1_B 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_cs2: weimcs2grp {
+ fsl,pins = <
+ /* nEXT_CS2 */
+ MX6QDL_PAD_SD2_DAT1__EIM_CS2_B 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_sram: weimsramgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
+ MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
+ /* Data */
+ MX6QDL_PAD_CSI0_DATA_EN__EIM_DATA00 0x1b0b0
+ MX6QDL_PAD_CSI0_VSYNC__EIM_DATA01 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT4__EIM_DATA02 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT5__EIM_DATA03 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT6__EIM_DATA04 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT7__EIM_DATA05 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT8__EIM_DATA06 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT9__EIM_DATA07 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT12__EIM_DATA08 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT13__EIM_DATA09 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT14__EIM_DATA10 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT15__EIM_DATA11 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT16__EIM_DATA12 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT17__EIM_DATA13 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT18__EIM_DATA14 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT19__EIM_DATA15 0x1b0b0
+ /* Address */
+ MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
+ MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
+ MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
+ MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
+ MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
+ MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
+ MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
+ MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
+ MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
+ MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
+ MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
+ MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
+ MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
+ MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
+ MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
+ MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
+ >;
+ };
+
+ pinctrl_weim_rdnwr: weimrdnwr {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CLK__GPIO1_IO10 0x0040
+ MX6QDL_PAD_RGMII_TD3__GPIO6_IO23 0x130b0
+ >;
+ };
+
+ pinctrl_weim_npwe: weimnpwe {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x0040
+ MX6QDL_PAD_RGMII_TD2__GPIO6_IO22 0x130b0
+ >;
+ };
+
+ /* ADDRESS[16:18] [25] used as GPIO */
+ pinctrl_weim_gpio_1: weimgpio-1 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x1b0b0
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ >;
+ };
+
+ /* ADDRESS[19:24] used as GPIO */
+ pinctrl_weim_gpio_2: weimgpio-2 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0
+ MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x1b0b0
+ MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x1b0b0
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ >;
+ };
+
+ /* DATA[16:31] used as GPIO */
+ pinctrl_weim_gpio_3: weimgpio-3 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x1b0b0
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x1b0b0
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x1b0b0
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0
+ MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x1b0b0
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x1b0b0
+ MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x1b0b0
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x1b0b0
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x1b0b0
+ MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
+ MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x1b0b0
+ MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x1b0b0
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
+ MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+
+ /* DQM[0:3] used as GPIO */
+ pinctrl_weim_gpio_4: weimgpio-4 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x1b0b0
+ MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x1b0b0
+ MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x1b0b0
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ >;
+ };
+
+ /* RDY used as GPIO */
+ pinctrl_weim_gpio_5: weimgpio-5 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x1b0b0
+ >;
+ };
+
+ /* ADDRESS[16] DATA[30] used as GPIO */
+ pinctrl_weim_gpio_6: weimgpio-6 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b0
+ MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
index a7100f99123e..54aca3a07ce4 100644
--- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
@@ -153,9 +153,9 @@
&clks {
assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
- <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
};
&ecspi3 {
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
index 8953eba0573d..88e5cb3b6be9 100644
--- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -154,9 +154,9 @@
&clks {
assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
- <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
};
&fec {
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
index 6ac41c7ed32e..1753ab720b0b 100644
--- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -144,9 +144,9 @@
&clks {
assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
- <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
};
&fec {
diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
index 805e23674a94..ee83161f674b 100644
--- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
@@ -291,7 +291,7 @@
MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
>;
- };
+ };
pinctrl_wdog: wdoggrp {
fsl,pins = <
diff --git a/arch/arm/boot/dts/imx6qdl-icore.dtsi b/arch/arm/boot/dts/imx6qdl-icore.dtsi
new file mode 100644
index 000000000000..023839a02dd0
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-icore.dtsi
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2016 Amarula Solutions B.V.
+ * Copyright (C) 2016 Engicam S.r.l.
+ *
+ * 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/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ memory {
+ reg = <0x10000000 0x80000000>;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_usb_h1_vbus: regulator-usb-h1-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator-usb-otg-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ rmii_clk: clock-rmii-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>; /* 25MHz for example */
+ };
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_3p3v>;
+};
+
+&can2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_3p3v>;
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LVDS2_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>;
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&rmii_clk>;
+ phy-mode = "rmii";
+ status = "okay";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ nand-on-flash-bbt;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x1b0b1
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b0
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b020
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b020
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b020
+ MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b020
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpmi-nand {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17070
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10070
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17070
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17070
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17070
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17070
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
index 880bd782a5b7..63acd54f5278 100644
--- a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
@@ -97,15 +97,6 @@
};
};
- bt_rfkill {
- compatible = "rfkill-gpio";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_bt_rfkill>;
- gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
- name = "bt_rfkill";
- type = <2>;
- };
-
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
@@ -160,7 +151,7 @@
};
};
- backlight_lcd {
+ backlight-lcd {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -169,7 +160,7 @@
status = "okay";
};
- backlight_lvds0: backlight_lvds0 {
+ backlight_lvds0: backlight-lvds0 {
compatible = "pwm-backlight";
pwms = <&pwm4 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -178,7 +169,7 @@
status = "okay";
};
- panel_lvds0 {
+ panel-lvds0 {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds0>;
@@ -328,19 +319,6 @@
>;
};
- pinctrl_bt_rfkill: bt_rfkillgrp {
- fsl,pins = <
- /* BT wake */
- MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
- /* BT reset */
- MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x0b0b0
- /* BT reg en */
- MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1b0b0
- /* BT host wake irq */
- MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x100b0
- >;
- };
-
pinctrl_ecspi1: ecspi1grp {
fsl,pins = <
MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
@@ -374,7 +352,7 @@
>;
};
- pinctrl_gpio_keys: gpio_keysgrp {
+ pinctrl_gpio_keys: gpio-keysgrp {
fsl,pins = <
/* Home Button: J14 pin 5 */
MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
@@ -457,7 +435,7 @@
>;
};
- pinctrl_wlan_vmmc: wlan_vmmcgrp {
+ pinctrl_wlan_vmmc: wlan-vmmcgrp {
fsl,pins = <
MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x030b0
>;
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
index b0b3220a1fd9..34887a10c5f1 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
@@ -229,7 +229,7 @@
};
};
- backlight_lcd: backlight_lcd {
+ backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -238,7 +238,7 @@
status = "okay";
};
- backlight_lvds0: backlight_lvds0 {
+ backlight_lvds0: backlight-lvds0 {
compatible = "pwm-backlight";
pwms = <&pwm4 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -247,7 +247,7 @@
status = "okay";
};
- backlight_lvds1: backlight_lvds1 {
+ backlight_lvds1: backlight-lvds1 {
compatible = "pwm-backlight";
pwms = <&pwm2 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -282,7 +282,7 @@
};
};
- panel_lcd {
+ panel-lcd {
compatible = "okaya,rs800480t-7x0gp";
backlight = <&backlight_lcd>;
@@ -293,7 +293,7 @@
};
};
- panel_lvds0 {
+ panel-lvds0 {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds0>;
@@ -304,7 +304,7 @@
};
};
- panel_lvds1 {
+ panel-lvds1 {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds1>;
@@ -447,7 +447,7 @@
};
&iomuxc {
- imx6q-nitrogen6_max {
+ imx6q-nitrogen6-max {
pinctrl_audmux: audmuxgrp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
@@ -504,7 +504,7 @@
>;
};
- pinctrl_gpio_keys: gpio_keysgrp {
+ pinctrl_gpio_keys: gpio-keysgrp {
fsl,pins = <
/* Power Button */
MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
@@ -720,7 +720,7 @@
>;
};
- pinctrl_wlan_vmmc: wlan_vmmcgrp {
+ pinctrl_wlan_vmmc: wlan-vmmcgrp {
fsl,pins = <
MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x100b0
MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
new file mode 100644
index 000000000000..d80f21abea62
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
@@ -0,0 +1,770 @@
+/*
+ * Copyright 2016 Boundary Devices, 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
+ * 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/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ backlight_lcd: backlight-lcd {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+
+ backlight_lvds0: backlight-lvds0 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+
+ backlight_lvds1: backlight-lvds1 {
+ compatible = "gpio-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight_lvds1>;
+ gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ default-on;
+ status = "okay";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ wakeup-source;
+ };
+
+ menu {
+ label = "Menu";
+ gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ };
+
+ home {
+ label = "Home";
+ gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ lcd_display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_j15>;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+
+ lcd_display_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lcd_display_out: endpoint {
+ remote-endpoint = <&lcd_panel_in>;
+ };
+ };
+ };
+
+ panel-lcd {
+ compatible = "okaya,rs800480t-7x0gp";
+ backlight = <&backlight_lcd>;
+
+ port {
+ lcd_panel_in: endpoint {
+ remote-endpoint = <&lcd_display_out>;
+ };
+ };
+ };
+
+ panel-lvds0 {
+ compatible = "hannstar,hsd100pxn1";
+ backlight = <&backlight_lvds0>;
+
+ port {
+ panel_in_lvds0: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+
+ panel-lvds1 {
+ compatible = "hannstar,hsd100pxn1";
+ backlight = <&backlight_lvds1>;
+
+ port {
+ panel_in_lvds1: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+
+ reg_1p8v: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_2p5v: regulator-2v5 {
+ compatible = "regulator-fixed";
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_can_xcvr: regulator-can-xcvr {
+ compatible = "regulator-fixed";
+ regulator-name = "CAN XCVR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_xcvr>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_usb_h1_vbus: regulator-usb-h1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_usb_otg_vbus: regulator-usb-otg-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_wlan_vmmc: regulator-wlan-vmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wlan_vmmc>;
+ regulator-name = "reg_wlan_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ sound {
+ compatible = "fsl,imx6q-nitrogen6_som2-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6q-nitrogen6_som2-sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sgtl5000>;
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <3>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ xceiver-supply = <&reg_can_xcvr>;
+ 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>;
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "microchip,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,err006687-workaround-present;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+
+ rtc@68 {
+ compatible = "st,rv4162";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rv4162>;
+ reg = <0x68>;
+ interrupts-extended = <&gpio6 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ touchscreen@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ touchscreen@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&iomuxc {
+ pinctrl_audmux: audmuxgrp {
+ 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_lvds1: backlight-lvds1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x0b0b0
+ >;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b0
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_can_xcvr: can-xcvrgrp {
+ fsl,pins = <
+ /* Flexcan XCVR enable */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x0b0b0
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x130b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0
+ MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x030b0
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio-keysgrp {
+ fsl,pins = <
+ /* Power Button */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ /* Menu Button */
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ /* Home Button */
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
+ /* Back Button */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ /* Volume Up Button */
+ MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
+ /* Volume Down Button */
+ MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c3mux: i2c3muxgrp {
+ fsl,pins = <
+ /* PCIe I2C enable */
+ MX6QDL_PAD_EIM_OE__GPIO2_IO25 0x000b0
+ >;
+ };
+
+ pinctrl_j15: j15grp {
+ fsl,pins = <
+ MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+ MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
+ MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
+ MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
+ MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
+ MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
+ MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
+ MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
+ MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
+ MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
+ MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
+ MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
+ MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
+ MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
+ MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
+ MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
+ MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
+ MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
+ MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
+ MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
+ MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
+ MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
+ MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
+ MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
+ MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
+ MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
+ MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
+ MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ /* PCIe reset */
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x030b0
+ MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x030b0
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x030b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x030b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x030b1
+ >;
+ };
+
+ pinctrl_rv4162: rv4162grp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x1b0b0
+ >;
+ };
+
+ pinctrl_sgtl5000: sgtl5000grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000b0
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x130b0
+ MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x130b0
+ MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24 0x130b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x030b0
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+ /* power enable, high active */
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x030b0
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10071
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17071
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17071
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10071
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17071
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17071
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17071
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17071
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17071
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_wlan_vmmc: wlan-vmmcgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x100b0
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x030b0
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x030b0
+ MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x000b0
+ >;
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&lcd_display_in>;
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_in_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_in_lvds1>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio6 31 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&ssi1 {
+ 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>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ non-removable;
+ vmmc-supply = <&reg_wlan_vmmc>;
+ cap-power-off-card;
+ keep-power-in-suspend;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ vmmc-supply = <&reg_1p8v>;
+ keep-power-in-suspend;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index db868bc42c0f..e476d01959ea 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -167,7 +167,7 @@
mux-ext-port = <3>;
};
- backlight_lcd: backlight_lcd {
+ backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -176,7 +176,7 @@
status = "okay";
};
- backlight_lvds: backlight_lvds {
+ backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
pwms = <&pwm4 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -211,7 +211,7 @@
};
};
- lcd_panel {
+ panel-lcd {
compatible = "okaya,rs800480t-7x0gp";
backlight = <&backlight_lcd>;
@@ -222,7 +222,7 @@
};
};
- panel {
+ panel-lvds0 {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds>;
@@ -413,7 +413,7 @@
>;
};
- pinctrl_gpio_keys: gpio_keysgrp {
+ pinctrl_gpio_keys: gpio-keysgrp {
fsl,pins = <
/* Power Button */
MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
@@ -561,7 +561,7 @@
>;
};
- pinctrl_wlan_vmmc: wlan_vmmcgrp {
+ pinctrl_wlan_vmmc: wlan-vmmcgrp {
fsl,pins = <
MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x100b0
MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
index e0280cac2484..e9801a26f3b4 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
@@ -427,10 +427,10 @@
};
&usdhc3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc3
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3
&pinctrl_usdhc3_cdwp>;
cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- status = "disabled";
+ status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index e000e6f12bf5..52390ba83e81 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -283,7 +283,7 @@
VD-supply = <&reg_audio>;
VLS-supply = <&reg_audio>;
VLC-supply = <&reg_audio>;
- };
+ };
};
@@ -613,8 +613,6 @@
&weim {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
- #address-cells = <2>;
- #size-cells = <1>;
ranges = <0 0 0x08000000 0x08000000>;
status = "disabled"; /* pin conflict with SPI NOR */
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 81dd6cd1937d..1f9076e271e4 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -153,7 +153,7 @@
mux-ext-port = <4>;
};
- backlight_lcd: backlight_lcd {
+ backlight_lcd: backlight-lcd {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -162,7 +162,7 @@
status = "okay";
};
- backlight_lvds: backlight_lvds {
+ backlight_lvds: backlight-lvds {
compatible = "pwm-backlight";
pwms = <&pwm4 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -197,7 +197,7 @@
};
};
- lcd_panel {
+ panel-lcd {
compatible = "okaya,rs800480t-7x0gp";
backlight = <&backlight_lcd>;
@@ -208,7 +208,7 @@
};
};
- panel {
+ panel-lvds0 {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds>;
@@ -378,7 +378,7 @@
>;
};
- pinctrl_gpio_keys: gpio_keysgrp {
+ pinctrl_gpio_keys: gpio-keysgrp {
fsl,pins = <
/* Power Button */
MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 8e9e0d98db2f..55ef53571fdd 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -129,8 +129,8 @@
pinctrl-0 = <&pinctrl_gpio_leds>;
red {
- gpios = <&gpio1 2 0>;
- default-state = "on";
+ gpios = <&gpio1 2 0>;
+ default-state = "on";
};
};
diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
index ac9529f85593..2bf2e623ac1e 100644
--- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
@@ -429,8 +429,8 @@
pinctrl_edt_ft5x06: edt-ft5x06grp {
fsl,pins = <
MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1b0b0 /* Interrupt */
- MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /* Reset */
- MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /* Wake */
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /* Reset */
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /* Wake */
>;
};
@@ -481,21 +481,21 @@
pinctrl_gpmi_nand: gpminandgrp {
fsl,pins = <
- MX6QDL_PAD_NANDF_CLE__NAND_CLE 0x0b0b1
- MX6QDL_PAD_NANDF_ALE__NAND_ALE 0x0b0b1
- MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0x0b0b1
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0x0b0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0x0b0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0x0b0b1
MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0x0b000
- MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0x0b0b1
- MX6QDL_PAD_SD4_CMD__NAND_RE_B 0x0b0b1
- MX6QDL_PAD_SD4_CLK__NAND_WE_B 0x0b0b1
- MX6QDL_PAD_NANDF_D0__NAND_DATA00 0x0b0b1
- MX6QDL_PAD_NANDF_D1__NAND_DATA01 0x0b0b1
- MX6QDL_PAD_NANDF_D2__NAND_DATA02 0x0b0b1
- MX6QDL_PAD_NANDF_D3__NAND_DATA03 0x0b0b1
- MX6QDL_PAD_NANDF_D4__NAND_DATA04 0x0b0b1
- MX6QDL_PAD_NANDF_D5__NAND_DATA05 0x0b0b1
- MX6QDL_PAD_NANDF_D6__NAND_DATA06 0x0b0b1
- MX6QDL_PAD_NANDF_D7__NAND_DATA07 0x0b0b1
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0x0b0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0x0b0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0x0b0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0x0b0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0x0b0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0x0b0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0x0b0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0x0b0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0x0b0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0x0b0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0x0b0b1
>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi
index ef7fa62b9898..a32089132263 100644
--- a/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi
@@ -28,7 +28,7 @@
MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000 /* RGMII_nRST */
MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x80000000 /* BT_ON */
MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x80000000 /* BT_WAKE */
- MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x80000000 /* BT_HOST_WAKE */
+ MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x80000000 /* BT_HOST_WAKE */
>;
};
};
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
index 2b9c2be436f9..82dc5744ae19 100644
--- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
@@ -129,8 +129,8 @@
pinctrl_i2c1: i2c1grp {
fsl,pins = <
- MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
- MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
>;
};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index b13b0b2db881..53e6e63cbb02 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -13,9 +13,10 @@
#include <dt-bindings/clock/imx6qdl-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include "skeleton.dtsi"
-
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
can0 = &can1;
@@ -204,9 +205,9 @@
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
- <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
- <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
- <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
<&clks IMX6QDL_CLK_LVDS1_GATE>,
<&clks IMX6QDL_CLK_PCIE_REF_125M>;
@@ -1092,10 +1093,13 @@
};
weim: weim@021b8000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
compatible = "fsl,imx6q-weim";
reg = <0x021b8000 0x4000>;
interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_EIM_SLOW>;
+ fsl,weim-cs-gpr = <&gpr>;
};
ocotp: ocotp@021bc000 {
diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
index 886dbf2eca49..0d4977ab7d29 100644
--- a/arch/arm/boot/dts/imx6qp.dtsi
+++ b/arch/arm/boot/dts/imx6qp.dtsi
@@ -85,5 +85,22 @@
pcie: pcie@0x01000000 {
compatible = "fsl,imx6qp-pcie", "snps,dw-pcie";
};
+
+ aips-bus@02100000 {
+ mmdc0: mmdc@021b0000 { /* MMDC0 */
+ compatible = "fsl,imx6qp-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+ };
};
};
+
+&ldb {
+ clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+ <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
+ <&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI0_PODF>, <&clks IMX6QDL_CLK_LDB_DI1_PODF>;
+ clock-names = "di0_pll", "di1_pll",
+ "di0_sel", "di1_sel", "di2_sel", "di3_sel",
+ "di0", "di1";
+};
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 02378db3f5fc..4fd6de29f07d 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -8,11 +8,13 @@
*/
#include <dt-bindings/interrupt-controller/irq.h>
-#include "skeleton.dtsi"
#include "imx6sl-pinfunc.h"
#include <dt-bindings/clock/imx6sl-clock.h>
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec;
gpio0 = &gpio1;
@@ -893,8 +895,11 @@
};
weim: weim@021b8000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
reg = <0x021b8000 0x4000>;
interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,weim-cs-gpr = <&gpr>;
};
ocotp: ocotp@021bc000 {
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi
index 9d70cfd40aff..da815527a7f8 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi
@@ -192,10 +192,10 @@
};
&i2c4 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c4>;
- status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
codec: wm8962@1a {
compatible = "wlf,wm8962";
@@ -290,6 +290,14 @@
status = "okay";
};
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts b/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts
new file mode 100644
index 000000000000..0c1fc1a8f913
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo-basic.dts
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * 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 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 "imx6sx-udoo-neo.dtsi"
+
+/ {
+ model = "UDOO Neo Basic";
+ compatible = "udoo,neobasic", "fsl,imx6sx";
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&fec1 {
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts b/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts
new file mode 100644
index 000000000000..5d6c2274ee2b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo-extended.dts
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * 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 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 "imx6sx-udoo-neo.dtsi"
+
+/ {
+ model = "UDOO Neo Extended";
+ compatible = "udoo,neoextended", "fsl,imx6sx";
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts b/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts
new file mode 100644
index 000000000000..653ceb29e28b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo-full.dts
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * 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 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 "imx6sx-udoo-neo.dtsi"
+
+/ {
+ model = "UDOO Neo Full";
+ compatible = "udoo,neofull", "fsl,imx6sx";
+
+ memory {
+ reg = <0x80000000 0x40000000>;
+ };
+};
+
+&fec1 {
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
new file mode 100644
index 000000000000..2b65d26f4396
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * 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 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.
+ */
+
+#include "imx6sx.dtsi"
+
+/ {
+ compatible = "fsl,imx6sx";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ red {
+ label = "udoo-neo:red:mmc";
+ gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "mmc0";
+ };
+
+ orange {
+ label = "udoo-neo:orange:user";
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
+ };
+ };
+
+ reg_sdio_pwr: regulator-sdio-pwr {
+ compatible = "regulator-fixed";
+ gpio = <&gpio6 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-name = "SDIO_PWR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+ soc-supply = <&sw1c_reg>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ pmic: pmic@08 {
+ 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>;
+ };
+
+ 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;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_enet1: enet1grp {
+ fsl,pins =
+ <MX6SX_PAD_ENET1_CRS__GPIO2_IO_1 0xa0b1>,
+ <MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1>,
+ <MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1>,
+ <MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1>,
+ <MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1>,
+ <MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1>,
+
+ <MX6SX_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x3081>,
+ <MX6SX_PAD_ENET2_TX_CLK__GPIO2_IO_9 0x3081>,
+ <MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081>,
+ <MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081>,
+ <MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081>,
+ <MX6SX_PAD_RGMII1_RXC__ENET1_RX_ER 0x3081>,
+
+ <MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x91>;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins =
+ <MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x4001b8b1>,
+ <MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1>;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins =
+ <MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1>,
+ <MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1>;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins =
+ <MX6SX_PAD_GPIO1_IO06__UART2_TX 0x1b0b1>,
+ <MX6SX_PAD_GPIO1_IO07__UART2_RX 0x1b0b1>;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins =
+ <MX6SX_PAD_SD4_DATA4__UART5_RX 0x1b0b1>,
+ <MX6SX_PAD_SD4_DATA5__UART5_TX 0x1b0b1>;
+ };
+
+ pinctrl_uart6: uart6grp {
+ fsl,pins =
+ <MX6SX_PAD_CSI_DATA00__UART6_RI_B 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA01__UART6_DSR_B 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA02__UART6_DTR_B 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA03__UART6_DCD_B 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA04__UART6_RX 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA05__UART6_TX 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA06__UART6_RTS_B 0x1b0b1>,
+ <MX6SX_PAD_CSI_DATA07__UART6_CTS_B 0x1b0b1>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins =
+ <MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059>,
+ <MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059>,
+ <MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059>,
+ <MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17059>,
+ <MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17059>,
+ <MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17059>,
+ <MX6SX_PAD_SD1_DATA0__GPIO6_IO_2 0x17059>; /* CD */
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* Cortex-M4 serial */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "disabled";
+};
+
+/* Arduino serial */
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "disabled";
+};
+
+&uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart6>;
+ uart-has-rtscts;
+ status = "disabled";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ vmmc-supply = <&reg_sdio_pwr>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ wakeup-source;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 1a473e83efbf..076a30f9bcae 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -11,9 +11,11 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "imx6sx-pinfunc.h"
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
can0 = &flexcan1;
can1 = &flexcan2;
@@ -858,7 +860,7 @@
fsl,num-tx-queues=<3>;
fsl,num-rx-queues=<3>;
status = "disabled";
- };
+ };
mlb: mlb@0218c000 {
reg = <0x0218c000 0x4000>;
@@ -968,10 +970,13 @@
};
weim: weim@021b8000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
compatible = "fsl,imx6sx-weim", "fsl,imx6q-weim";
reg = <0x021b8000 0x4000>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_EIM_SLOW>;
+ fsl,weim-cs-gpr = <&gpr>;
};
ocotp: ocotp@021bc000 {
@@ -1143,7 +1148,7 @@
lcdif1: lcdif@02220000 {
compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
reg = <0x02220000 0x4000>;
- interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_EDGE_RISING>;
clocks = <&clks IMX6SX_CLK_LCDIF1_PIX>,
<&clks IMX6SX_CLK_LCDIF_APB>,
<&clks IMX6SX_CLK_DISPLAY_AXI>;
@@ -1154,7 +1159,7 @@
lcdif2: lcdif@02224000 {
compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
reg = <0x02224000 0x4000>;
- interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_EDGE_RISING>;
clocks = <&clks IMX6SX_CLK_LCDIF2_PIX>,
<&clks IMX6SX_CLK_LCDIF_APB>,
<&clks IMX6SX_CLK_DISPLAY_AXI>;
@@ -1181,7 +1186,7 @@
fsl,adck-max-frequency = <30000000>, <40000000>,
<20000000>;
status = "disabled";
- };
+ };
adc2: adc@02284000 {
compatible = "fsl,imx6sx-adc", "fsl,vf610-adc";
@@ -1192,7 +1197,7 @@
fsl,adck-max-frequency = <30000000>, <40000000>,
<20000000>;
status = "disabled";
- };
+ };
wdog3: wdog@02288000 {
compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index e281d5087d4a..00f98e5bfcaf 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -225,7 +225,7 @@
};
&usbotg1 {
- dr_mode = "peripheral";
+ dr_mode = "otg";
status = "okay";
};
@@ -235,6 +235,14 @@
status = "okay";
};
+&usbphy1 {
+ fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+ fsl,tx-d-cal = <106>;
+};
+
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
diff --git a/arch/arm/boot/dts/imx6ul-liteboard.dts b/arch/arm/boot/dts/imx6ul-liteboard.dts
new file mode 100644
index 000000000000..6e04cb9202f4
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-liteboard.dts
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2016 Grinn
+ *
+ * Author: Marcin Niestroj <m.niestroj@grinn-global.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
+ * 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 "imx6ul-litesom.dtsi"
+
+/ {
+ model = "Grinn i.MX6UL liteBoard";
+ compatible = "grinn,imx6ul-liteboard", "grinn,imx6ul-litesom",
+ "fsl,imx6ul";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_otg1_vbus>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 8 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&iomuxc {
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO07__ENET1_MDC 0x1b0b0
+ MX6UL_PAD_GPIO1_IO06__ENET1_MDIO 0x1b0b0
+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
+ >;
+ };
+
+ pinctrl_usb_otg1_vbus: usb-otg1-vbus {
+ fsl,pins = <
+ MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x79
+ >;
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ wakeup-source;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul-litesom.dtsi b/arch/arm/boot/dts/imx6ul-litesom.dtsi
new file mode 100644
index 000000000000..461292d33417
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-litesom.dtsi
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Grinn
+ *
+ * Author: Marcin Niestroj <m.niestroj@grinn-global.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
+ * 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 "imx6ul.dtsi"
+
+/ {
+ model = "Grinn i.MX6UL liteSOM";
+ compatible = "grinn,imx6ul-litesom", "fsl,imx6ul";
+
+ memory {
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&iomuxc {
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+ MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+ MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+ MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+ MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+ MX6UL_PAD_NAND_ALE__USDHC2_RESET_B 0x17059
+ >;
+ };
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ no-1-8-v;
+ non-removable;
+ keep-power-in-suspend;
+ wakeup-source;
+ bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index c5c05fdccc78..39845a7e0463 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -11,9 +11,11 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "imx6ul-pinfunc.h"
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
ethernet0 = &fec1;
ethernet1 = &fec2;
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk.dts b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
new file mode 100644
index 000000000000..db5bc076e1cc
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, 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
+ * 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 "imx6ul-14x14-evk.dts"
+
+/ {
+ model = "Freescale i.MX6 UlltraLite 14x14 EVK Board";
+ compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
+ assigned-clock-rates = <320000000>;
+};
diff --git a/arch/arm/boot/dts/imx6ull-pinfunc.h b/arch/arm/boot/dts/imx6ull-pinfunc.h
new file mode 100644
index 000000000000..118202336691
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-pinfunc.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DTS_IMX6ULL_PINFUNC_H
+#define __DTS_IMX6ULL_PINFUNC_H
+
+#include "imx6ul-pinfunc.h"
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6ULL_PAD_ENET2_RX_DATA0__EPDC_SDDO08 0x00E4 0x0370 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_RX_DATA1__EPDC_SDDO09 0x00E8 0x0374 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_RX_EN__EPDC_SDDO10 0x00EC 0x0378 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_TX_DATA0__EPDC_SDDO11 0x00F0 0x037C 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_TX_DATA1__EPDC_SDDO12 0x00F4 0x0380 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_TX_EN__EPDC_SDDO13 0x00F8 0x0384 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_TX_CLK__EPDC_SDDO14 0x00FC 0x0388 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET2_RX_ER__EPDC_SDDO15 0x0100 0x038C 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_CLK__EPDC_SDCLK 0x0104 0x0390 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_ENABLE__EPDC_SDLE 0x0108 0x0394 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_HSYNC__EPDC_SDOE 0x010C 0x0398 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_VSYNC__EPDC_SDCE0 0x0110 0x039C 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_RESET__EPDC_GDOE 0x0114 0x03A0 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA00__EPDC_SDDO00 0x0118 0x03A4 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA01__EPDC_SDDO01 0x011C 0x03A8 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA02__EPDC_SDDO02 0x0120 0x03AC 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA03__EPDC_SDDO03 0x0124 0x03B0 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA04__EPDC_SDDO04 0x0128 0x03B4 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA05__EPDC_SDDO05 0x012C 0x03B8 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA06__EPDC_SDDO06 0x0130 0x03BC 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA07__EPDC_SDDO07 0x0134 0x03C0 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA14__EPDC_SDSHR 0x0150 0x03DC 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA15__EPDC_GDRL 0x0154 0x03E0 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA16__EPDC_GDCLK 0x0158 0x03E4 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA17__EPDC_GDSP 0x015C 0x03E8 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA21__EPDC_SDCE1 0x016C 0x03F8 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_MCLK__ESAI_TX3_RX2 0x01D4 0x0460 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_PIXCLK__ESAI_TX2_RX3 0x01D8 0x0464 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_VSYNC__ESAI_TX4_RX1 0x01DC 0x0468 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_HSYNC__ESAI_TX1 0x01E0 0x046C 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA00__ESAI_TX_HF_CLK 0x01E4 0x0470 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA01__ESAI_RX_HF_CLK 0x01E8 0x0474 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA02__ESAI_RX_FS 0x01EC 0x0478 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA03__ESAI_RX_CLK 0x01F0 0x047C 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0
+#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0
+
+#endif /* __DTS_IMX6ULL_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
new file mode 100644
index 000000000000..dee8ab8135e1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, 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
+ * 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 "imx6ul.dtsi"
+#include "imx6ull-pinfunc.h"
diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
index 3f9f0d9c8094..7bc3c00e56c6 100644
--- a/arch/arm/boot/dts/imx7d-pinfunc.h
+++ b/arch/arm/boot/dts/imx7d-pinfunc.h
@@ -43,26 +43,30 @@
#define MX7D_PAD_GPIO1_IO04__GPIO1_IO4 0x0010 0x0040 0x0000 0x0 0x0
#define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC 0x0010 0x0040 0x072C 0x1 0x1
#define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4 0x0010 0x0040 0x0594 0x2 0x1
-#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B 0x0010 0x0040 0x0710 0x3 0x4
+#define MX7D_PAD_GPIO1_IO04__UART5_DCE_CTS 0x0010 0x0040 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO04__UART5_DTE_RTS 0x0010 0x0040 0x0710 0x3 0x4
#define MX7D_PAD_GPIO1_IO04__I2C1_SCL 0x0010 0x0040 0x05D4 0x4 0x2
#define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT 0x0010 0x0040 0x0000 0x6 0x0
#define MX7D_PAD_GPIO1_IO05__GPIO1_IO5 0x0014 0x0044 0x0000 0x0 0x0
#define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR 0x0014 0x0044 0x0000 0x1 0x0
#define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5 0x0014 0x0044 0x0598 0x2 0x1
-#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B 0x0014 0x0044 0x0710 0x3 0x5
+#define MX7D_PAD_GPIO1_IO05__UART5_DCE_RTS 0x0014 0x0044 0x0710 0x3 0x5
+#define MX7D_PAD_GPIO1_IO05__UART5_DTE_CTS 0x0014 0x0044 0x0000 0x3 0x0
#define MX7D_PAD_GPIO1_IO05__I2C1_SDA 0x0014 0x0044 0x05D8 0x4 0x2
#define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT 0x0014 0x0044 0x0000 0x6 0x0
#define MX7D_PAD_GPIO1_IO06__GPIO1_IO6 0x0018 0x0048 0x0000 0x0 0x0
#define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC 0x0018 0x0048 0x0728 0x1 0x1
#define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6 0x0018 0x0048 0x059C 0x2 0x1
-#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA 0x0018 0x0048 0x0714 0x3 0x4
+#define MX7D_PAD_GPIO1_IO06__UART5_DCE_RX 0x0018 0x0048 0x0714 0x3 0x4
+#define MX7D_PAD_GPIO1_IO06__UART5_DTE_TX 0x0018 0x0048 0x0000 0x3 0x0
#define MX7D_PAD_GPIO1_IO06__I2C2_SCL 0x0018 0x0048 0x05DC 0x4 0x2
#define MX7D_PAD_GPIO1_IO06__CCM_WAIT 0x0018 0x0048 0x0000 0x5 0x0
#define MX7D_PAD_GPIO1_IO06__KPP_ROW4 0x0018 0x0048 0x0624 0x6 0x1
#define MX7D_PAD_GPIO1_IO07__GPIO1_IO7 0x001C 0x004C 0x0000 0x0 0x0
#define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR 0x001C 0x004C 0x0000 0x1 0x0
#define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7 0x001C 0x004C 0x05A0 0x2 0x1
-#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA 0x001C 0x004C 0x0714 0x3 0x5
+#define MX7D_PAD_GPIO1_IO07__UART5_DCE_TX 0x001C 0x004C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO07__UART5_DTE_RX 0x001C 0x004C 0x0714 0x3 0x5
#define MX7D_PAD_GPIO1_IO07__I2C2_SDA 0x001C 0x004C 0x05E0 0x4 0x2
#define MX7D_PAD_GPIO1_IO07__CCM_STOP 0x001C 0x004C 0x0000 0x5 0x0
#define MX7D_PAD_GPIO1_IO07__KPP_COL4 0x001C 0x004C 0x0604 0x6 0x1
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 2b6cb05bc01a..8ff2cbdd8f0d 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -46,9 +46,11 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "imx7d-pinfunc.h"
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
aliases {
gpio0 = &gpio1;
gpio1 = &gpio2;
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts
index 6f16d09dc5a4..e8b249f92fb3 100644
--- a/arch/arm/boot/dts/integratorap.dts
+++ b/arch/arm/boot/dts/integratorap.dts
@@ -10,6 +10,41 @@
compatible = "arm,integrator-ap";
dma-ranges = <0x80000000 0x0 0x80000000>;
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ /*
+ * Since the board has pluggable CPU modules, we
+ * cannot define a proper compatible here. Let the
+ * boot loader fill in the apropriate compatible
+ * string if necessary.
+ */
+ /* compatible = "arm,arm926ej-s"; */
+ reg = <0>;
+ /*
+ * The documentation in ARM DUI 0138E page 3-12 states
+ * that the maximum frequency for this clock is 200 MHz
+ * but painful trial-and-error has proved to me that it
+ * is actually just hanging the system above 71 MHz.
+ * Sad but true.
+ */
+ /* kHz uV */
+ operating-points = <71000 0
+ 66000 0
+ 60000 0
+ 48000 0
+ 36000 0
+ 24000 0
+ 12000 0>;
+ clocks = <&cmosc>;
+ clock-names = "cpu";
+ clock-latency = <1000000>; /* 1 ms */
+ };
+ };
+
aliases {
arm,timer-primary = &timer2;
arm,timer-secondary = &timer1;
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
index 1b5e4b006b72..97f38b57a702 100644
--- a/arch/arm/boot/dts/integratorcp.dts
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -13,6 +13,32 @@
bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
};
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ /*
+ * Since the board has pluggable CPU modules, we
+ * cannot define a proper compatible here. Let the
+ * boot loader fill in the apropriate compatible
+ * string if necessary.
+ */
+ /* compatible = "arm,arm920t"; */
+ reg = <0>;
+ /*
+ * TBD comment.
+ */
+ /* kHz uV */
+ operating-points = <50000 0
+ 48000 0>;
+ clocks = <&cmcore>;
+ clock-names = "cpu";
+ clock-latency = <1000000>; /* 1 ms */
+ };
+ };
+
/*
* The Integrator/CP overall clocking architecture can be found in
* ARM DUI 0184B page 7-28 "Integrator/CP922T system clocks" which
diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
index 2919c5190653..63c7cf0c6b6d 100644
--- a/arch/arm/boot/dts/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/keystone-k2g.dtsi
@@ -72,6 +72,7 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
compatible = "ti,keystone","simple-bus";
ranges = <0x0 0x0 0x0 0xc0000000>;
dma-ranges = <0x80000000 0x8 0x00000000 0x80000000>;
diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi
index 2ee3d0ac2816..0c5e74e79ba2 100644
--- a/arch/arm/boot/dts/keystone-k2l.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l.dtsi
@@ -59,6 +59,7 @@
reg = <0x02620690 0xc>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <2>;
pinctrl-single,bit-per-mux;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x1>;
diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts
index 1e9a72100a45..330aada6d33f 100644
--- a/arch/arm/boot/dts/kirkwood-topkick.dts
+++ b/arch/arm/boot/dts/kirkwood-topkick.dts
@@ -4,7 +4,7 @@
#include "kirkwood-6282.dtsi"
/ {
- model = "Univeral Scientific Industrial Co. Topkick-1281P2";
+ model = "Universal Scientific Industrial Co. Topkick-1281P2";
compatible = "usi,topkick-1281P2", "usi,topkick", "marvell,kirkwood-88f6282", "marvell,kirkwood";
memory {
diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index b5841fab51c1..d81fe433e3c8 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -479,6 +479,8 @@
compatible = "nxp,lpc3220-pwm";
reg = <0x4005C000 0x4>;
clocks = <&clk LPC32XX_CLK_PWM1>;
+ assigned-clocks = <&clk LPC32XX_CLK_PWM1>;
+ assigned-clock-parents = <&clk LPC32XX_CLK_PERIPH>;
status = "disabled";
};
@@ -486,6 +488,8 @@
compatible = "nxp,lpc3220-pwm";
reg = <0x4005C004 0x4>;
clocks = <&clk LPC32XX_CLK_PWM2>;
+ assigned-clocks = <&clk LPC32XX_CLK_PWM2>;
+ assigned-clock-parents = <&clk LPC32XX_CLK_PERIPH>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 368e21934285..282d854f4342 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -47,6 +47,7 @@
#include "skeleton64.dtsi"
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "fsl,ls1021a";
@@ -70,14 +71,15 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu@f00 {
+ cpu0: cpu@f00 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0xf00>;
clocks = <&cluster1_clk>;
+ #cooling-cells = <2>;
};
- cpu@f01 {
+ cpu1: cpu@f01 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0xf01>;
@@ -251,6 +253,84 @@
};
};
+ tmu: tmu@1f00000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0x0 0x1f00000 0x0 0x10000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x30061>;
+ fsl,tmu-calibration = <0x00000000 0x0000000f
+ 0x00000001 0x00000017
+ 0x00000002 0x0000001e
+ 0x00000003 0x00000026
+ 0x00000004 0x0000002e
+ 0x00000005 0x00000035
+ 0x00000006 0x0000003d
+ 0x00000007 0x00000044
+ 0x00000008 0x0000004c
+ 0x00000009 0x00000053
+ 0x0000000a 0x0000005b
+ 0x0000000b 0x00000064
+
+ 0x00010000 0x00000011
+ 0x00010001 0x0000001c
+ 0x00010002 0x00000024
+ 0x00010003 0x0000002b
+ 0x00010004 0x00000034
+ 0x00010005 0x00000039
+ 0x00010006 0x00000042
+ 0x00010007 0x0000004c
+ 0x00010008 0x00000051
+ 0x00010009 0x0000005a
+ 0x0001000a 0x00000063
+
+ 0x00020000 0x00000013
+ 0x00020001 0x00000019
+ 0x00020002 0x00000024
+ 0x00020003 0x0000002c
+ 0x00020004 0x00000035
+ 0x00020005 0x0000003d
+ 0x00020006 0x00000046
+ 0x00020007 0x00000050
+ 0x00020008 0x00000059
+
+ 0x00030000 0x00000002
+ 0x00030001 0x0000000d
+ 0x00030002 0x00000019
+ 0x00030003 0x00000024>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+
+ thermal-sensors = <&tmu 0>;
+
+ trips {
+ cpu_alert: cpu-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit: cpu-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
dspi0: dspi@2100000 {
compatible = "fsl,ls1021a-v1.0-dspi";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/mps2-an385.dts b/arch/arm/boot/dts/mps2-an385.dts
index 31c374d72a6f..aebbebfc25d1 100644
--- a/arch/arm/boot/dts/mps2-an385.dts
+++ b/arch/arm/boot/dts/mps2-an385.dts
@@ -59,7 +59,7 @@
stdout-path = "serial0:9600n8";
};
- memory {
+ memory@21000000 {
device_type = "memory";
reg = <0x21000000 0x1000000>;
};
diff --git a/arch/arm/boot/dts/mps2-an399.dts b/arch/arm/boot/dts/mps2-an399.dts
index 5e7e5ca2edbf..349abf70b2a5 100644
--- a/arch/arm/boot/dts/mps2-an399.dts
+++ b/arch/arm/boot/dts/mps2-an399.dts
@@ -59,7 +59,7 @@
stdout-path = "serial0:9600n8";
};
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x1000000>;
};
diff --git a/arch/arm/boot/dts/mps2.dtsi b/arch/arm/boot/dts/mps2.dtsi
index efb8a03cb970..23467390558d 100644
--- a/arch/arm/boot/dts/mps2.dtsi
+++ b/arch/arm/boot/dts/mps2.dtsi
@@ -42,10 +42,12 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "skeleton.dtsi"
#include "armv7-m.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
oscclk0: clk-osc0 {
compatible = "fixed-clock";
#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 18596a2c58a1..7eab6f4c4665 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -12,8 +12,10 @@
* GNU General Public License for more details.
*/
+#include <dt-bindings/clock/mt2701-clk.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/mt2701-resets.h>
#include "skeleton64.dtsi"
#include "mt2701-pinfunc.h"
@@ -71,10 +73,18 @@
#clock-cells = <0>;
};
- uart_clk: dummy26m {
+ clk26m: oscillator@0 {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <26000000>;
+ clock-output-names = "clk26m";
+ };
+
+ rtc32k: oscillator@1 {
+ compatible = "fixed-clock";
#clock-cells = <0>;
+ clock-frequency = <32000>;
+ clock-output-names = "rtc32k";
};
timer {
@@ -104,6 +114,26 @@
reg = <0 0x10005000 0 0x1000>;
};
+ topckgen: syscon@10000000 {
+ compatible = "mediatek,mt2701-topckgen", "syscon";
+ reg = <0 0x10000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ infracfg: syscon@10001000 {
+ compatible = "mediatek,mt2701-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ pericfg: syscon@10003000 {
+ compatible = "mediatek,mt2701-pericfg", "syscon";
+ reg = <0 0x10003000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
watchdog: watchdog@10007000 {
compatible = "mediatek,mt2701-wdt",
"mediatek,mt6589-wdt";
@@ -128,6 +158,12 @@
reg = <0 0x10200100 0 0x1c>;
};
+ apmixedsys: syscon@10209000 {
+ compatible = "mediatek,mt2701-apmixedsys", "syscon";
+ reg = <0 0x10209000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
gic: interrupt-controller@10211000 {
compatible = "arm,cortex-a7-gic";
interrupt-controller;
@@ -144,7 +180,8 @@
"mediatek,mt6577-uart";
reg = <0 0x11002000 0 0x400>;
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&uart_clk>;
+ clocks = <&pericfg CLK_PERI_UART0_SEL>, <&pericfg CLK_PERI_UART0>;
+ clock-names = "baud", "bus";
status = "disabled";
};
@@ -153,7 +190,8 @@
"mediatek,mt6577-uart";
reg = <0 0x11003000 0 0x400>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&uart_clk>;
+ clocks = <&pericfg CLK_PERI_UART1_SEL>, <&pericfg CLK_PERI_UART1>;
+ clock-names = "baud", "bus";
status = "disabled";
};
@@ -162,7 +200,8 @@
"mediatek,mt6577-uart";
reg = <0 0x11004000 0 0x400>;
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&uart_clk>;
+ clocks = <&pericfg CLK_PERI_UART2_SEL>, <&pericfg CLK_PERI_UART2>;
+ clock-names = "baud", "bus";
status = "disabled";
};
@@ -171,7 +210,8 @@
"mediatek,mt6577-uart";
reg = <0 0x11005000 0 0x400>;
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&uart_clk>;
+ clocks = <&pericfg CLK_PERI_UART3_SEL>, <&pericfg CLK_PERI_UART3>;
+ clock-names = "baud", "bus";
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi
index fb712b9aa874..aba542d63d6d 100644
--- a/arch/arm/boot/dts/omap2420.dtsi
+++ b/arch/arm/boot/dts/omap2420.dtsi
@@ -38,6 +38,7 @@
reg = <0x0 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
ranges = <0 0x0 0x1000>;
omap2420_pmx: pinmux@30 {
@@ -46,6 +47,7 @@
reg = <0x30 0x0113>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <8>;
pinctrl-single,function-mask = <0x3f>;
};
diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi
index 455aaea407dd..84635eeb99cd 100644
--- a/arch/arm/boot/dts/omap2430.dtsi
+++ b/arch/arm/boot/dts/omap2430.dtsi
@@ -38,6 +38,7 @@
reg = <0x2000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
ranges = <0 0x2000 0x1000>;
omap2430_pmx: pinmux@30 {
@@ -46,6 +47,7 @@
reg = <0x30 0x0154>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <8>;
pinctrl-single,function-mask = <0x3f>;
};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 353d818ce5a6..ecf5eb584c75 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -106,6 +106,7 @@
reg = <0x30 0x238>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
@@ -145,6 +146,7 @@
reg = <0xa00 0x5c>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi
index e41c52d3b113..834fdf13601f 100644
--- a/arch/arm/boot/dts/omap34xx.dtsi
+++ b/arch/arm/boot/dts/omap34xx.dtsi
@@ -34,6 +34,7 @@
reg = <0x480025d8 0x24>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi
index 718fa88407cd..d1a3e56b50ce 100644
--- a/arch/arm/boot/dts/omap36xx.dtsi
+++ b/arch/arm/boot/dts/omap36xx.dtsi
@@ -66,6 +66,7 @@
reg = <0x480025a0 0x5c>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts
new file mode 100644
index 000000000000..f3ccb4ceed9e
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts
@@ -0,0 +1,188 @@
+/*
+ * 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 "omap443x.dtsi"
+
+/ {
+ model = "Motorola Droid 4 XT894";
+ compatible = "motorola,droid4", "ti,omap4430", "ti,omap4";
+
+ chosen {
+ stdout-path = &uart3;
+ };
+
+ /*
+ * We seem to have only 1021 MB accessible, 1021 - 1022 is locked,
+ * then 1023 - 1024 seems to contain mbm. For SRAM, see the notes
+ * below about SRAM and L3_ICLK2 being unused by default,
+ */
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x3fd00000>; /* 1021 MB */
+ };
+
+ /* CPCAP really supports 1650000 to 3400000 range */
+ vmmc: regulator-mmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ /* CPCAP really supports 3000000 to 3100000 range */
+ vemmc: regulator-emmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vemmc";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ /* CPCAP really supports 1650000 to 1950000 range */
+ wl12xx_vmmc: regulator-wl12xx {
+ compatible = "regulator-fixed";
+ regulator-name = "vwl1271";
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1650000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>; /* gpio94 */
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+};
+
+/* L3_2 interconnect is unused, SRAM, GPMC and L3_ICLK2 disabled */
+&gpmc {
+ status = "disabled";
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc>;
+ bus-width = <4>;
+ cd-gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* gpio106 */
+};
+
+&mmc2 {
+ vmmc-supply = <&vemmc>;
+ bus-width = <8>;
+ non-removable;
+};
+
+&mmc3 {
+ vmmc-supply = <&wl12xx_vmmc>;
+ interrupts-extended = <&wakeupgen GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core 0xde>;
+
+ non-removable;
+ bus-width = <4>;
+ cap-power-off-card;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1283";
+ reg = <2>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; /* gpio100 */
+ ref-clock-frequency = <26000000>;
+ tcxo-clock-frequency = <26000000>;
+ };
+};
+
+/* L3_2 interconnect is unused, SRAM, GPMC and L3_ICLK2 disabled */
+&ocmcram {
+ status = "disabled";
+};
+
+&omap4_pmx_core {
+ usb_gpio_mux_sel1: pinmux_usb_gpio_mux_sel1_pins {
+ /* gpio_60 */
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3)
+ >;
+ };
+
+ usb_ulpi_pins: pinmux_usb_ulpi_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x196, MUX_MODE7)
+ OMAP4_IOPAD(0x198, MUX_MODE7)
+ OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1ba, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1bc, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE0)
+ OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE0)
+ >;
+ };
+
+ /* usb0_otg_dp and usb0_otg_dm */
+ usb_utmi_pins: pinmux_usb_utmi_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0)
+ OMAP4_IOPAD(0x198, PIN_INPUT | MUX_MODE0)
+ OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1ba, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1bc, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+
+ /* uart3_tx_irtx and uart3_rx_irrx */
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x196, MUX_MODE7)
+ OMAP4_IOPAD(0x198, MUX_MODE7)
+ OMAP4_IOPAD(0x1b2, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1b6, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1b8, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1ba, MUX_MODE2)
+ OMAP4_IOPAD(0x1bc, PIN_INPUT | MUX_MODE2)
+ OMAP4_IOPAD(0x1be, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c0, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c2, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c4, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c6, PIN_INPUT_PULLUP | MUX_MODE7)
+ OMAP4_IOPAD(0x1c8, PIN_INPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+};
+
+&omap4_pmx_wkup {
+ usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
+ /* gpio_wk0 */
+ pinctrl-single,pins = <
+ OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
+ >;
+ };
+};
+
+&uart3 {
+ interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core 0x17c>;
+};
+
+/* Internal UTMI+ PHY used for OTG, CPCAP ULPI PHY for detection and charger */
+&usb_otg_hs {
+ interface-type = <1>;
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 0ced079b7ae3..8087456b5fbe 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -184,6 +184,7 @@
reg = <0x40 0x0196>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
@@ -256,6 +257,7 @@
reg = <0x1e040 0x0038>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
index 53d31a87b44b..a8c72611fbe3 100644
--- a/arch/arm/boot/dts/omap5-uevm.dts
+++ b/arch/arm/boot/dts/omap5-uevm.dts
@@ -27,12 +27,98 @@
default-state = "off";
};
};
+
+ evm_keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&evm_keys_pins>;
+
+ #address-cells = <7>;
+ #size-cells = <0>;
+
+ btn1 {
+ label = "BTN1";
+ linux,code = <169>;
+ gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; /* gpio3_83 */
+ wakeup-source;
+ autorepeat;
+ debounce_interval = <50>;
+ };
+ };
+
+ evm_leds {
+ compatible = "gpio-leds";
+
+ led1 {
+ label = "omap5:red:led";
+ gpios = <&gpio9 17 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led2 {
+ label = "omap5:green:led";
+ gpios = <&gpio9 18 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc1";
+ default-state = "off";
+ };
+
+ led3 {
+ label = "omap5:blue:led";
+ gpios = <&gpio9 19 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc2";
+ default-state = "off";
+ };
+
+ led4 {
+ label = "omap5:green:led1";
+ gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led5 {
+ label = "omap5:green:led2";
+ gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ default-state = "off";
+ };
+
+ led6 {
+ label = "omap5:green:led3";
+ gpios = <&gpio9 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led7 {
+ label = "omap5:green:led4";
+ gpios = <&gpio9 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ default-state = "off";
+ };
+
+ led8 {
+ label = "omap5:green:led5";
+ gpios = <&gpio9 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
};
&hdmi {
vdda-supply = <&ldo4_reg>;
};
+&i2c1 {
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+};
+
&i2c5 {
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
@@ -48,6 +134,12 @@
};
&omap5_pmx_core {
+ evm_keys_pins: pinmux_evm_keys_gpio_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0b6, PIN_INPUT | MUX_MODE6) /* gpio3_83 */
+ >;
+ };
+
i2c5_pins: pinmux_i2c5_pins {
pinctrl-single,pins = <
OMAP5_IOPAD(0x1c6, PIN_INPUT | MUX_MODE0) /* i2c5_scl */
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 25262118ec3d..968c67a49dbd 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -171,6 +171,7 @@
reg = <0x40 0x01b6>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
@@ -270,6 +271,7 @@
reg = <0xc840 0x003c>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
#interrupt-cells = <1>;
interrupt-controller;
pinctrl-single,register-width = <16>;
diff --git a/arch/arm/boot/dts/orion5x-lschl.dts b/arch/arm/boot/dts/orion5x-lschl.dts
new file mode 100644
index 000000000000..947409252845
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-lschl.dts
@@ -0,0 +1,171 @@
+/*
+ * Device Tree file for Buffalo Linkstation LS-CHLv3
+ *
+ * Copyright (C) 2016 Ash Hughes <ashley.hughes@blueyonder.co.uk>
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@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 , 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 "orion5x-linkstation.dtsi"
+#include "mvebu-linkstation-gpio-simple.dtsi"
+#include "mvebu-linkstation-fan.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Buffalo Linkstation Live v3 (LS-CHL)";
+ compatible = "buffalo,lschl", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+ memory { /* 128 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ gpio_keys {
+ func {
+ label = "Function Button";
+ linux,code = <KEY_OPTION>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ };
+
+ power-on-switch {
+ gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+ };
+
+ power-auto-switch {
+ gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_leds {
+ pinctrl-0 = <&pmx_led_power &pmx_led_alarm &pmx_led_info &pmx_led_func>;
+ blue-power-led {
+ gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+ };
+
+ red-alarm-led {
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ };
+
+ amber-info-led {
+ gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+ };
+
+ func {
+ label = "lschl:func:blue:top";
+ gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_fan {
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW
+ &gpio0 16 GPIO_ACTIVE_LOW>;
+
+ alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&pinctrl {
+ pmx_led_power: pmx-leds {
+ marvell,pins = "mpp0";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_hdd: pmx-power-hdd {
+ marvell,pins = "mpp1";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_alarm: pmx-leds {
+ marvell,pins = "mpp2";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_info: pmx-leds {
+ marvell,pins = "mpp3";
+ marvell,function = "gpio";
+ };
+
+ pmx_fan_lock: pmx-fan-lock {
+ marvell,pins = "mpp6";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_switch: pmx-power-switch {
+ marvell,pins = "mpp8", "mpp10", "mpp15";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_usb: pmx-power-usb {
+ marvell,pins = "mpp9";
+ marvell,function = "gpio";
+ };
+
+ pmx_fan_high: pmx-fan-high {
+ marvell,pins = "mpp14";
+ marvell,function = "gpio";
+ };
+
+ pmx_fan_low: pmx-fan-low {
+ marvell,pins = "mpp16";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_func: pmx-leds {
+ marvell,pins = "mpp17";
+ marvell,function = "gpio";
+ };
+
+ pmx_sw_init: pmx-sw-init {
+ marvell,pins = "mpp7";
+ marvell,function = "gpio";
+ };
+};
+
+&hdd_power {
+ gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+};
+
+&usb_power {
+ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+};
+
diff --git a/arch/arm/boot/dts/ox820.dtsi b/arch/arm/boot/dts/ox820.dtsi
new file mode 100644
index 000000000000..e40f282a023a
--- /dev/null
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -0,0 +1,296 @@
+/*
+ * ox820.dtsi - Device tree file for Oxford Semiconductor OX820 SoC
+ *
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "oxsemi,ox820";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "oxsemi,ox820-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm11mpcore";
+ clocks = <&armclk>;
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,arm11mpcore";
+ clocks = <&armclk>;
+ reg = <1>;
+ };
+ };
+
+ memory {
+ /* Max 512MB @ 0x60000000 */
+ reg = <0x60000000 0x20000000>;
+ };
+
+ clocks {
+ osc: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ gmacclk: gmacclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ };
+
+ sysclk: sysclk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clocks = <&osc>;
+ };
+
+ plla: plla {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <850000000>;
+ };
+
+ armclk: armclk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&plla>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ interrupt-parent = <&gic>;
+
+ nandc: nand-controller@41000000 {
+ compatible = "oxsemi,ox820-nand";
+ reg = <0x41000000 0x100000>;
+ clocks = <&stdclk 11>;
+ resets = <&reset 15>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ etha: ethernet@40400000 {
+ compatible = "oxsemi,ox820-dwmac", "snps,dwmac";
+ reg = <0x40400000 0x2000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ mac-address = [000000000000]; /* Filled in by U-Boot */
+ phy-mode = "rgmii";
+
+ clocks = <&stdclk 9>, <&gmacclk>;
+ clock-names = "gmac", "stmmaceth";
+ resets = <&reset 6>;
+
+ /* Regmap for sys registers */
+ oxsemi,sys-ctrl = <&sys>;
+
+ status = "disabled";
+ };
+
+ apb-bridge@44000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0x44000000 0x1000000>;
+
+ pinctrl: pinctrl {
+ compatible = "oxsemi,ox820-pinctrl";
+
+ /* Regmap for sys registers */
+ oxsemi,sys-ctrl = <&sys>;
+
+ pinctrl_uart0: uart0 {
+ uart0 {
+ pins = "gpio30", "gpio31";
+ function = "fct5";
+ };
+ };
+
+ pinctrl_uart0_modem: uart0_modem {
+ uart0_modem_a {
+ pins = "gpio24", "gpio24", "gpio26", "gpio27";
+ function = "fct4";
+ };
+ uart0_modem_b {
+ pins = "gpio28", "gpio29";
+ function = "fct5";
+ };
+ };
+
+ pinctrl_uart1: uart1 {
+ uart1 {
+ pins = "gpio7", "gpio8";
+ function = "fct4";
+ };
+ };
+
+ pinctrl_uart1_modem: uart1_modem {
+ uart1_modem {
+ pins = "gpio5", "gpio6", "gpio40", "gpio41", "gpio42", "gpio43";
+ function = "fct4";
+ };
+ };
+
+ pinctrl_etha_mdio: etha_mdio {
+ etha_mdio {
+ pins = "gpio3", "gpio4";
+ function = "fct1";
+ };
+ };
+
+ pinctrl_nand: nand {
+ nand {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15",
+ "gpio16", "gpio17", "gpio18", "gpio19",
+ "gpio20", "gpio21", "gpio22", "gpio23",
+ "gpio24";
+ function = "fct1";
+ };
+ };
+ };
+
+ gpio0: gpio@000000 {
+ compatible = "oxsemi,ox820-gpio";
+ reg = <0x000000 0x100000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ngpios = <32>;
+ oxsemi,gpio-bank = <0>;
+ gpio-ranges = <&pinctrl 0 0 32>;
+ };
+
+ gpio1: gpio@100000 {
+ compatible = "oxsemi,ox820-gpio";
+ reg = <0x100000 0x100000>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ngpios = <18>;
+ oxsemi,gpio-bank = <1>;
+ gpio-ranges = <&pinctrl 0 32 18>;
+ };
+
+ uart0: serial@200000 {
+ compatible = "ns16550a";
+ reg = <0x200000 0x100000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <0>;
+ fifo-size = <16>;
+ reg-io-width = <1>;
+ current-speed = <115200>;
+ no-loopback-test;
+ status = "disabled";
+ clocks = <&sysclk>;
+ resets = <&reset 17>;
+ };
+
+ uart1: serial@300000 {
+ compatible = "ns16550a";
+ reg = <0x200000 0x100000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <0>;
+ fifo-size = <16>;
+ reg-io-width = <1>;
+ current-speed = <115200>;
+ no-loopback-test;
+ status = "disabled";
+ clocks = <&sysclk>;
+ resets = <&reset 18>;
+ };
+
+ rps@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0x400000 0x100000>;
+
+ intc: interrupt-controller@0 {
+ compatible = "oxsemi,ox820-rps-irq", "oxsemi,ox810se-rps-irq";
+ interrupt-controller;
+ reg = <0 0x200>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ valid-mask = <0xFFFFFFFF>;
+ clear-mask = <0>;
+ };
+
+ timer0: timer@200 {
+ compatible = "oxsemi,ox820-rps-timer";
+ reg = <0x200 0x40>;
+ clocks = <&sysclk>;
+ interrupt-parent = <&intc>;
+ interrupts = <4>;
+ };
+ };
+
+ sys: sys-ctrl@e00000 {
+ compatible = "oxsemi,ox820-sys-ctrl", "syscon", "simple-mfd";
+ reg = <0xe00000 0x200000>;
+
+ reset: reset-controller {
+ compatible = "oxsemi,ox820-reset", "oxsemi,ox810se-reset";
+ #reset-cells = <1>;
+ };
+
+ stdclk: stdclk {
+ compatible = "oxsemi,ox820-stdclk", "oxsemi,ox810se-stdclk";
+ #clock-cells = <1>;
+ };
+ };
+ };
+
+ apb-bridge@47000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0x47000000 0x1000000>;
+
+ scu: scu@0 {
+ compatible = "arm,arm11mp-scu";
+ reg = <0x0 0x100>;
+ };
+
+ local-timer@600 {
+ compatible = "arm,arm11mp-twd-timer";
+ reg = <0x600 0x20>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3)|IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&armclk>;
+ };
+
+ gic: gic@1000 {
+ compatible = "arm,arm11mp-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x1000 0x1000>,
+ <0x100 0x500>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa25x.dtsi b/arch/arm/boot/dts/pxa25x.dtsi
new file mode 100644
index 000000000000..f9f4726396a0
--- /dev/null
+++ b/arch/arm/boot/dts/pxa25x.dtsi
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * 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 "pxa2xx.dtsi"
+#include "dt-bindings/clock/pxa-clock.h"
+
+/ {
+ model = "Marvell PXA25x family SoC";
+ compatible = "marvell,pxa250";
+
+ clocks {
+ /*
+ * The muxing of external clocks/internal dividers for osc* clock
+ * sources has been hidden under the carpet by now.
+ */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clks: pxa2xx_clks@41300004 {
+ compatible = "marvell,pxa250-core-clocks";
+ #clock-cells = <1>;
+ status = "okay";
+ };
+
+ /* timer oscillator */
+ clktimer: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <3686400>;
+ clock-output-names = "ostimer";
+ };
+ };
+
+ pxabus {
+ pdma: dma-controller@40000000 {
+ compatible = "marvell,pdma-1.0";
+ reg = <0x40000000 0x10000>;
+ interrupts = <25>;
+ #dma-channels = <16>;
+ #dma-cells = <2>;
+ #dma-requests = <40>;
+ status = "okay";
+ };
+
+ pxairq: interrupt-controller@40d00000 {
+ marvell,intc-priority;
+ marvell,intc-nr-irqs = <32>;
+ };
+
+ pinctrl: pinctrl@40e00000 {
+ reg = <0x40e00054 0x20 0x40e0000c 0xc 0x40e0010c 4
+ 0x40f00020 0x10>;
+ compatible = "marvell,pxa25x-pinctrl";
+ };
+
+ gpio: gpio@40e00000 {
+ compatible = "intel,pxa25x-gpio";
+ gpio-ranges = <&pinctrl 0 0 84>;
+ clocks = <&clks CLK_NONE>;
+ };
+
+ pwm0: pwm@40b00000 {
+ compatible = "marvell,pxa250-pwm";
+ reg = <0x40b00000 0x10>;
+ #pwm-cells = <1>;
+ clocks = <&clks CLK_PWM0>;
+ };
+
+ pwm1: pwm@40b00010 {
+ compatible = "marvell,pxa250-pwm";
+ reg = <0x40b00010 0x10>;
+ #pwm-cells = <1>;
+ clocks = <&clks CLK_PWM1>;
+ };
+ };
+
+ timer@40a00000 {
+ compatible = "marvell,pxa-timer";
+ reg = <0x40a00000 0x20>;
+ interrupts = <26>;
+ clocks = <&clktimer>;
+ status = "okay";
+ };
+
+ pxa250_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+
+ opp@99532800 {
+ opp-hz = /bits/ 64 <99532800>;
+ opp-microvolt = <1000000 950000 1650000>;
+ clock-latency-ns = <20>;
+ };
+ opp@199065600 {
+ opp-hz = /bits/ 64 <199065600>;
+ opp-microvolt = <1000000 950000 1650000>;
+ clock-latency-ns = <20>;
+ };
+ opp@298598400 {
+ opp-hz = /bits/ 64 <298598400>;
+ opp-microvolt = <1100000 1045000 1650000>;
+ clock-latency-ns = <20>;
+ };
+ opp@398131200 {
+ opp-hz = /bits/ 64 <398131200>;
+ opp-microvolt = <1300000 1235000 1650000>;
+ clock-latency-ns = <20>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index 9e73dc6b3ed3..e0fab48ba6fa 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -137,4 +137,44 @@
clocks = <&clks CLK_OSTIMER>;
status = "okay";
};
+
+ pxa270_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+
+ opp@104000000 {
+ opp-hz = /bits/ 64 <104000000>;
+ opp-microvolt = <900000 900000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ opp@156000000 {
+ opp-hz = /bits/ 64 <156000000>;
+ opp-microvolt = <1000000 1000000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ opp@208000000 {
+ opp-hz = /bits/ 64 <208000000>;
+ opp-microvolt = <1180000 1180000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ opp@312000000 {
+ opp-hz = /bits/ 64 <312000000>;
+ opp-microvolt = <1250000 1250000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ opp@416000000 {
+ opp-hz = /bits/ 64 <416000000>;
+ opp-microvolt = <1350000 1350000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ opp@520000000 {
+ opp-hz = /bits/ 64 <520000000>;
+ opp-microvolt = <1450000 1450000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ opp@624000000 {
+ opp-hz = /bits/ 64 <624000000>;
+ opp-microvolt = <1550000 1550000 1705000>;
+ clock-latency-ns = <20>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
index 3ff077ca4400..e4ebcde17837 100644
--- a/arch/arm/boot/dts/pxa2xx.dtsi
+++ b/arch/arm/boot/dts/pxa2xx.dtsi
@@ -54,8 +54,8 @@
reg = <0x40e00000 0x10000>;
gpio-controller;
#gpio-cells = <0x2>;
- interrupts = <10>;
- interrupt-names = "gpio_mux";
+ interrupts = <8>, <9>, <10>;
+ interrupt-names = "gpio0", "gpio1", "gpio_mux";
interrupt-controller;
#interrupt-cells = <0x2>;
ranges;
diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi
index 9d6f3aacedb7..7a0cc4ea819a 100644
--- a/arch/arm/boot/dts/pxa3xx.dtsi
+++ b/arch/arm/boot/dts/pxa3xx.dtsi
@@ -138,6 +138,7 @@
reg = <0x40e10000 0xffff>;
#address-cells = <1>;
#size-cells = <0>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x7>;
};
diff --git a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
index 6c0038398ef2..4b8872cc8bf9 100644
--- a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
@@ -51,6 +51,29 @@
regulator-boot-on;
};
+ /* GPIO controlled ethernet power regulator */
+ dragon_veth: xc622a331mrg {
+ compatible = "regulator-fixed";
+ regulator-name = "XC6222A331MR-G";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vph>;
+ gpio = <&pm8058_gpio 40 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dragon_veth_gpios>;
+ regulator-always-on;
+ };
+
+ /* VDDvario fixed regulator */
+ dragon_vario: nds332p {
+ compatible = "regulator-fixed";
+ regulator-name = "NDS332P";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&pm8058_s3>;
+ };
+
/* This is a levelshifter for SDCC5 */
dragon_vio_txb: txb0104rgyr {
compatible = "regulator-fixed";
@@ -167,6 +190,36 @@
bias-pull-up;
};
};
+
+ dragon_ebi2_pins: ebi2 {
+ /*
+ * Pins used by EBI2 on the Dragonboard, actually only
+ * CS2 is used by a real peripheral. CS0 is just
+ * routed to a test point.
+ */
+ mux0 {
+ pins =
+ /* "gpio39", CS1A_N this is not good to mux */
+ "gpio40", /* CS2A_N */
+ "gpio134"; /* CS0_N testpoint TP29 */
+ function = "ebi2cs";
+ };
+ mux1 {
+ pins =
+ /* EBI2_ADDR_7 downto EBI2_ADDR_0 address bus */
+ "gpio123", "gpio124", "gpio125", "gpio126",
+ "gpio127", "gpio128", "gpio129", "gpio130",
+ /* EBI2_DATA_15 downto EBI2_DATA_0 data bus */
+ "gpio135", "gpio136", "gpio137", "gpio138",
+ "gpio139", "gpio140", "gpio141", "gpio142",
+ "gpio143", "gpio144", "gpio145", "gpio146",
+ "gpio147", "gpio148", "gpio149", "gpio150",
+ "gpio151", /* EBI2_OE_N */
+ "gpio153", /* EBI2_ADV */
+ "gpio157"; /* EBI2_WE_N */
+ function = "ebi2";
+ };
+ };
};
qcom,ssbi@500000 {
@@ -201,6 +254,15 @@
};
gpio@150 {
+ dragon_ethernet_gpios: ethernet-gpios {
+ pinconf {
+ pins = "gpio7";
+ function = "normal";
+ input-enable;
+ bias-disable;
+ power-source = <PM8058_GPIO_S3>;
+ };
+ };
dragon_bmp085_gpios: bmp085-gpios {
pinconf {
pins = "gpio16";
@@ -238,6 +300,14 @@
power-source = <PM8058_GPIO_S3>;
};
};
+ dragon_veth_gpios: veth-gpios {
+ pinconf {
+ pins = "gpio40";
+ function = "normal";
+ bias-disable;
+ drive-push-pull;
+ };
+ };
};
led@48 {
@@ -322,6 +392,55 @@
};
};
+ external-bus@1a100000 {
+ /* The EBI2 will instantiate first, then populate its children */
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dragon_ebi2_pins>;
+
+ /*
+ * An on-board SMSC LAN9221 chip for "debug ethernet",
+ * which is actually just an ordinary ethernet on the
+ * EBI2. This has a 25MHz chrystal next to it, so no
+ * clocking is needed.
+ */
+ ethernet-ebi2@2,0 {
+ compatible = "smsc,lan9221", "smsc,lan9115";
+ reg = <2 0x0 0x100>;
+ /*
+ * GPIO7 has interrupt 198 on the PM8058
+ * The second interrupt is the PME interrupt
+ * for network wakeup, connected to the TLMM.
+ */
+ interrupts-extended = <&pmicintc 198 IRQ_TYPE_EDGE_FALLING>,
+ <&tlmm 29 IRQ_TYPE_EDGE_RISING>;
+ reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
+ vdd33a-supply = <&dragon_veth>;
+ vddvario-supply = <&dragon_vario>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dragon_ethernet_gpios>;
+ phy-mode = "mii";
+ reg-io-width = <2>;
+ smsc,force-external-phy;
+ /* IRQ on edge falling = active low */
+ smsc,irq-active-low;
+ smsc,irq-push-pull;
+
+ /*
+ * SLOW chipselect config
+ * Delay 9 cycles (140ns@64MHz) between SMSC
+ * LAN9221 Ethernet controller reads and writes
+ * on CS2.
+ */
+ qcom,xmem-recovery-cycles = <0>;
+ qcom,xmem-write-hold-cycles = <3>;
+ qcom,xmem-write-delta-cycles = <31>;
+ qcom,xmem-read-delta-cycles = <28>;
+ qcom,xmem-write-wait-cycles = <9>;
+ qcom,xmem-read-wait-cycles = <9>;
+ };
+ };
+
rpm@104000 {
/*
* Set up of the PMIC RPM regulators for this board
diff --git a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts
index b72e09506448..e39440a86739 100644
--- a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts
@@ -15,6 +15,20 @@
stdout-path = "serial0:115200n8";
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ ramoops@88d00000{
+ compatible = "ramoops";
+ reg = <0x88d00000 0x100000>;
+ record-size = <0x00020000>;
+ console-size = <0x00020000>;
+ ftrace-size = <0x00020000>;
+ };
+ };
+
ext_3p3v: regulator-fixed@1 {
compatible = "regulator-fixed";
regulator-min-microvolt = <3300000>;
@@ -99,6 +113,7 @@
l2 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
+ regulator-always-on;
};
/* msm_otg-HSUSB_3p3 */
@@ -133,13 +148,14 @@
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
bias-pull-down;
+ regulator-always-on;
};
/* pwm_power for backlight */
l17 {
regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3600000>;
- bias-pull-down;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
};
/* camera, qdsp6 */
@@ -184,6 +200,63 @@
};
};
+ mdp@5100000 {
+ status = "okay";
+ ports {
+ port@1 {
+ mdp_dsi1_out: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+ };
+ };
+
+ dsi0: mdss_dsi@4700000 {
+ status = "okay";
+ vdda-supply = <&pm8921_l2>;/*VDD_MIPI1 to 4*/
+ vdd-supply = <&pm8921_l8>;
+ vddio-supply = <&pm8921_lvs7>;
+ avdd-supply = <&pm8921_l11>;
+ vcss-supply = <&ext_3p3v>;
+
+ panel@0 {
+ reg = <0>;
+ compatible = "jdi,lt070me05000";
+
+ vddp-supply = <&pm8921_l17>;
+ iovcc-supply = <&pm8921_lvs7>;
+
+ enable-gpios = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_LOW>;
+ dcdc-en-gpios = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+ };
+ ports {
+ port@0 {
+ dsi0_in: endpoint {
+ remote-endpoint = <&mdp_dsi1_out>;
+ };
+ };
+
+ port@1 {
+ dsi0_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+ };
+ };
+
+ dsi-phy@4700200 {
+ status = "okay";
+ vddio-supply = <&pm8921_lvs7>;/*VDD_PLL2_1 to 7*/
+ };
+
gsbi@16200000 {
status = "okay";
qcom,mode = <GSBI_PROT_I2C>;
diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index 2eeb0904eaa7..3d37cab3b9a9 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -43,6 +43,17 @@
};
};
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "d";
+
+ port {
+ hdmi_con: endpoint {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+ };
+
soc {
pinctrl@800000 {
card_detect: card_detect {
@@ -64,6 +75,25 @@
bias-disable;
};
};
+
+ hdmi_pinctrl: hdmi-pinctrl {
+ mux {
+ pins = "gpio70", "gpio71", "gpio72";
+ function = "hdmi";
+ };
+
+ pinconf_ddc {
+ pins = "gpio70", "gpio71";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ pinconf_hpd {
+ pins = "gpio72";
+ bias-pull-down;
+ drive-strength = <16>;
+ };
+ };
};
rpm@108000 {
@@ -329,5 +359,49 @@
mmc-pwrseq = <&sdcc4_pwrseq>;
};
};
+
+ hdmi-tx@4a00000 {
+ status = "okay";
+
+ core-vdda-supply = <&pm8921_hdmi_switch>;
+ hdmi-mux-supply = <&ext_3p3v>;
+
+ hpd-gpios = <&tlmm_pinmux 72 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_pinctrl>;
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <&mdp_dtv_out>;
+ };
+ };
+
+ port@1 {
+ endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
+
+ hdmi-phy@4a00400 {
+ status = "okay";
+
+ core-vdda-supply = <&pm8921_hdmi_switch>;
+ };
+
+ mdp@5100000 {
+ status = "okay";
+
+ ports {
+ port@3 {
+ endpoint {
+ remote-endpoint = <&hdmi_in>;
+ };
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 1dbe697b2e90..268bd470c865 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -1060,6 +1060,231 @@
reg = <0x1a400000 0x100>;
};
+ gpu: adreno-3xx@4300000 {
+ compatible = "qcom,adreno-3xx";
+ reg = <0x04300000 0x20000>;
+ reg-names = "kgsl_3d0_reg_memory";
+ interrupts = <GIC_SPI 80 0>;
+ interrupt-names = "kgsl_3d0_irq";
+ clock-names =
+ "core_clk",
+ "iface_clk",
+ "mem_clk",
+ "mem_iface_clk";
+ clocks =
+ <&mmcc GFX3D_CLK>,
+ <&mmcc GFX3D_AHB_CLK>,
+ <&mmcc GFX3D_AXI_CLK>,
+ <&mmcc MMSS_IMEM_AHB_CLK>;
+ qcom,chipid = <0x03020002>;
+
+ iommus = <&gfx3d 0
+ &gfx3d 1
+ &gfx3d 2
+ &gfx3d 3
+ &gfx3d 4
+ &gfx3d 5
+ &gfx3d 6
+ &gfx3d 7
+ &gfx3d 8
+ &gfx3d 9
+ &gfx3d 10
+ &gfx3d 11
+ &gfx3d 12
+ &gfx3d 13
+ &gfx3d 14
+ &gfx3d 15
+ &gfx3d 16
+ &gfx3d 17
+ &gfx3d 18
+ &gfx3d 19
+ &gfx3d 20
+ &gfx3d 21
+ &gfx3d 22
+ &gfx3d 23
+ &gfx3d 24
+ &gfx3d 25
+ &gfx3d 26
+ &gfx3d 27
+ &gfx3d 28
+ &gfx3d 29
+ &gfx3d 30
+ &gfx3d 31
+ &gfx3d1 0
+ &gfx3d1 1
+ &gfx3d1 2
+ &gfx3d1 3
+ &gfx3d1 4
+ &gfx3d1 5
+ &gfx3d1 6
+ &gfx3d1 7
+ &gfx3d1 8
+ &gfx3d1 9
+ &gfx3d1 10
+ &gfx3d1 11
+ &gfx3d1 12
+ &gfx3d1 13
+ &gfx3d1 14
+ &gfx3d1 15
+ &gfx3d1 16
+ &gfx3d1 17
+ &gfx3d1 18
+ &gfx3d1 19
+ &gfx3d1 20
+ &gfx3d1 21
+ &gfx3d1 22
+ &gfx3d1 23
+ &gfx3d1 24
+ &gfx3d1 25
+ &gfx3d1 26
+ &gfx3d1 27
+ &gfx3d1 28
+ &gfx3d1 29
+ &gfx3d1 30
+ &gfx3d1 31>;
+
+ qcom,gpu-pwrlevels {
+ compatible = "qcom,gpu-pwrlevels";
+ qcom,gpu-pwrlevel@0 {
+ qcom,gpu-freq = <450000000>;
+ };
+ qcom,gpu-pwrlevel@1 {
+ qcom,gpu-freq = <27000000>;
+ };
+ };
+ };
+
+ mmss_sfpb: syscon@5700000 {
+ compatible = "syscon";
+ reg = <0x5700000 0x70>;
+ };
+
+ dsi0: mdss_dsi@4700000 {
+ compatible = "qcom,mdss-dsi-ctrl";
+ label = "MDSS DSI CTRL->0";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 82 0>;
+ reg = <0x04700000 0x200>;
+ reg-names = "dsi_ctrl";
+
+ clocks = <&mmcc DSI_M_AHB_CLK>,
+ <&mmcc DSI_S_AHB_CLK>,
+ <&mmcc AMP_AHB_CLK>,
+ <&mmcc DSI_CLK>,
+ <&mmcc DSI1_BYTE_CLK>,
+ <&mmcc DSI_PIXEL_CLK>,
+ <&mmcc DSI1_ESC_CLK>;
+ clock-names = "iface_clk", "bus_clk", "core_mmss_clk",
+ "src_clk", "byte_clk", "pixel_clk",
+ "core_clk";
+
+ assigned-clocks = <&mmcc DSI1_BYTE_SRC>,
+ <&mmcc DSI1_ESC_SRC>,
+ <&mmcc DSI_SRC>,
+ <&mmcc DSI_PIXEL_SRC>;
+ assigned-clock-parents = <&dsi0_phy 0>,
+ <&dsi0_phy 0>,
+ <&dsi0_phy 1>,
+ <&dsi0_phy 1>;
+ syscon-sfpb = <&mmss_sfpb>;
+ phys = <&dsi0_phy>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi0_in: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi0_out: endpoint {
+ };
+ };
+ };
+ };
+
+
+ dsi0_phy: dsi-phy@4700200 {
+ compatible = "qcom,dsi-phy-28nm-8960";
+ #clock-cells = <1>;
+
+ reg = <0x04700200 0x100>,
+ <0x04700300 0x200>,
+ <0x04700500 0x5c>;
+ reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator";
+ clock-names = "iface_clk";
+ clocks = <&mmcc DSI_M_AHB_CLK>;
+ };
+
+
+ mdp_port0: iommu@7500000 {
+ compatible = "qcom,apq8064-iommu";
+ #iommu-cells = <1>;
+ clock-names =
+ "smmu_pclk",
+ "iommu_clk";
+ clocks =
+ <&mmcc SMMU_AHB_CLK>,
+ <&mmcc MDP_AXI_CLK>;
+ reg = <0x07500000 0x100000>;
+ interrupts =
+ <GIC_SPI 63 0>,
+ <GIC_SPI 64 0>;
+ qcom,ncb = <2>;
+ };
+
+ mdp_port1: iommu@7600000 {
+ compatible = "qcom,apq8064-iommu";
+ #iommu-cells = <1>;
+ clock-names =
+ "smmu_pclk",
+ "iommu_clk";
+ clocks =
+ <&mmcc SMMU_AHB_CLK>,
+ <&mmcc MDP_AXI_CLK>;
+ reg = <0x07600000 0x100000>;
+ interrupts =
+ <GIC_SPI 61 0>,
+ <GIC_SPI 62 0>;
+ qcom,ncb = <2>;
+ };
+
+ gfx3d: iommu@7c00000 {
+ compatible = "qcom,apq8064-iommu";
+ #iommu-cells = <1>;
+ clock-names =
+ "smmu_pclk",
+ "iommu_clk";
+ clocks =
+ <&mmcc SMMU_AHB_CLK>,
+ <&mmcc GFX3D_AXI_CLK>;
+ reg = <0x07c00000 0x100000>;
+ interrupts =
+ <GIC_SPI 69 0>,
+ <GIC_SPI 70 0>;
+ qcom,ncb = <3>;
+ };
+
+ gfx3d1: iommu@7d00000 {
+ compatible = "qcom,apq8064-iommu";
+ #iommu-cells = <1>;
+ clock-names =
+ "smmu_pclk",
+ "iommu_clk";
+ clocks =
+ <&mmcc SMMU_AHB_CLK>,
+ <&mmcc GFX3D_AXI_CLK>;
+ reg = <0x07d00000 0x100000>;
+ interrupts =
+ <GIC_SPI 210 0>,
+ <GIC_SPI 211 0>;
+ qcom,ncb = <3>;
+ };
+
pcie: pci@1b500000 {
compatible = "qcom,pcie-apq8064", "snps,dw-pcie";
reg = <0x1b500000 0x1000
@@ -1095,6 +1320,102 @@
reset-names = "axi", "ahb", "por", "pci", "phy";
status = "disabled";
};
+
+ hdmi: hdmi-tx@4a00000 {
+ compatible = "qcom,hdmi-tx-8960";
+ reg = <0x04a00000 0x2f0>;
+ reg-names = "core_physical";
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mmcc HDMI_APP_CLK>,
+ <&mmcc HDMI_M_AHB_CLK>,
+ <&mmcc HDMI_S_AHB_CLK>;
+ clock-names = "core_clk",
+ "master_iface_clk",
+ "slave_iface_clk";
+
+ phys = <&hdmi_phy>;
+ phy-names = "hdmi-phy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ hdmi_in: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ hdmi_out: endpoint {
+ };
+ };
+ };
+ };
+
+ hdmi_phy: hdmi-phy@4a00400 {
+ compatible = "qcom,hdmi-phy-8960";
+ reg = <0x4a00400 0x60>,
+ <0x4a00500 0x100>;
+ reg-names = "hdmi_phy",
+ "hdmi_pll";
+
+ clocks = <&mmcc HDMI_S_AHB_CLK>;
+ clock-names = "slave_iface_clk";
+ };
+
+ mdp: mdp@5100000 {
+ compatible = "qcom,mdp4";
+ reg = <0x05100000 0xf0000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mmcc MDP_CLK>,
+ <&mmcc MDP_AHB_CLK>,
+ <&mmcc MDP_AXI_CLK>,
+ <&mmcc MDP_LUT_CLK>,
+ <&mmcc HDMI_TV_CLK>,
+ <&mmcc MDP_TV_CLK>;
+ clock-names = "core_clk",
+ "iface_clk",
+ "bus_clk",
+ "lut_clk",
+ "hdmi_clk",
+ "tv_clk";
+
+ iommus = <&mdp_port0 0
+ &mdp_port0 2
+ &mdp_port1 0
+ &mdp_port1 2>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mdp_lvds_out: endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ mdp_dsi1_out: endpoint {
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ mdp_dsi2_out: endpoint {
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ mdp_dtv_out: endpoint {
+ };
+ };
+ };
+ };
};
};
#include "qcom-apq8064-pins.dtsi"
diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 39eb7a4ed16a..80d48867107f 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -182,13 +182,13 @@
};
clocks {
- xo_board {
+ xo_board: xo_board {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <19200000>;
};
- sleep_clk {
+ sleep_clk: sleep_clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
@@ -416,8 +416,10 @@
reg-names = "hc_mem", "core_mem";
interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
- clock-names = "core", "iface";
+ clocks = <&gcc GCC_SDCC1_APPS_CLK>,
+ <&gcc GCC_SDCC1_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
status = "disabled";
};
@@ -427,8 +429,10 @@
reg-names = "hc_mem", "core_mem";
interrupts = <0 125 0>, <0 221 0>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
- clock-names = "core", "iface";
+ clocks = <&gcc GCC_SDCC2_APPS_CLK>,
+ <&gcc GCC_SDCC2_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/qcom-mdm9615-wp8548-mangoh-green.dts b/arch/arm/boot/dts/qcom-mdm9615-wp8548-mangoh-green.dts
new file mode 100644
index 000000000000..26160c324802
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-mdm9615-wp8548-mangoh-green.dts
@@ -0,0 +1,281 @@
+/*
+ * Device Tree Source for mangOH Green Board with WP8548 Module
+ *
+ * Copyright (C) 2016 BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.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/input/input.h>
+
+#include "qcom-mdm9615-wp8548.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MangOH Green with WP8548 Module";
+ compatible = "swir,mangoh-green-wp8548", "swir,wp8548", "qcom,mdm9615";
+
+ aliases {
+ spi0 = &gsbi3_spi;
+ serial0 = &gsbi4_serial;
+ serial1 = &gsbi5_serial;
+ i2c0 = &gsbi5_i2c;
+ mmc0 = &sdcc1;
+ };
+
+ chosen {
+ stdout-path = "serial1:115200n8";
+ };
+};
+
+&msmgpio {
+ /* MangOH GPIO Mapping :
+ * - 2 : GPIOEXP_INT2
+ * - 7 : IOT1_GPIO2
+ * - 8 : IOT0_GPIO4
+ * - 13: IOT0_GPIO3
+ * - 21: IOT1_GPIO4
+ * - 22: IOT2_GPIO1
+ * - 23: IOT2_GPIO2
+ * - 24: IOT2_GPIO3
+ * - 25: IOT1_GPIO1
+ * - 32: IOT1_GPIO3
+ * - 33: IOT0_GPIO2
+ * - 42: IOT0_GPIO1 and SD Card Detect
+ */
+
+ gpioext1_pins: gpioext1_pins {
+ pins {
+ pins = "gpio2";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ sdc_cd_pins: sdc_cd_pins {
+ pins {
+ pins = "gpio42";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+};
+
+&gsbi3_spi {
+ spi@0 {
+ compatible = "swir,mangoh-iotport-spi", "spidev";
+ spi-max-frequency = <24000000>;
+ reg = <0>;
+ };
+};
+
+&gsbi5_i2c {
+ mux@71 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x71>;
+
+ i2c_iot0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c_iot1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c_iot2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ usbhub: hub@8 {
+ compatible = "smsc,usb3503a";
+ reg = <0x8>;
+ connect-gpios = <&gpioext2 1 GPIO_ACTIVE_HIGH>;
+ intn-gpios = <&gpioext2 0 GPIO_ACTIVE_LOW>;
+ initial-mode = <1>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ gpioext0: gpio@3e {
+ /* GPIO Expander 0 Mapping :
+ * - 0: ARDUINO_RESET_Level shift
+ * - 1: BattChrgr_PG_N
+ * - 2: BattGauge_GPIO
+ * - 3: LED_ON (out active high)
+ * - 4: ATmega_reset_GPIO
+ * - 5: X
+ * - 6: PCM_ANALOG_SELECT (out active high)
+ * - 7: X
+ * - 8: Board_rev_res1 (in)
+ * - 9: Board_rev_res2 (in)
+ * - 10: UART_EXP1_ENn (out active low / pull-down)
+ * - 11: UART_EXP1_IN (out pull-down)
+ * - 12: UART_EXP2_IN (out pull-down)
+ * - 13: SDIO_SEL (out pull-down)
+ * - 14: SPI_EXP1_ENn (out active low / pull-down)
+ * - 15: SPI_EXP1_IN (out pull-down)
+ */
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "semtech,sx1509q";
+ reg = <0x3e>;
+ interrupt-parent = <&gpioext1>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+
+ probe-reset;
+
+ gpio-controller;
+ interrupt-controller;
+ };
+ };
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ gpioext1: gpio@3f {
+ /* GPIO Expander 1 Mapping :
+ * - 0: GPIOEXP_INT1
+ * - 1: Battery detect
+ * - 2: GPIO_SCF3_RESET
+ * - 3: LED_CARD_DETECT_IOT0 (in)
+ * - 4: LED_CARD_DETECT_IOT1 (in)
+ * - 5: LED_CARD_DETECT_IOT2 (in)
+ * - 6: UIM2_PWM_SELECT
+ * - 7: UIM2_M2_S_SELECT
+ * - 8: TP900
+ * - 9: SENSOR_INT1 (in)
+ * - 10: SENSOR_INT2 (in)
+ * - 11: CARD_DETECT_IOT0 (in pull-up)
+ * - 12: CARD_DETECT_IOT2 (in pull-up)
+ * - 13: CARD_DETECT_IOT1 (in pull-up)
+ * - 14: GPIOEXP_INT3 (in active low / pull-up)
+ * - 15: BattChrgr_INT_N
+ */
+ pinctrl-0 = <&gpioext1_pins>;
+ pinctrl-names = "default";
+
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "semtech,sx1509q";
+ reg = <0x3f>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+
+ probe-reset;
+
+ gpio-controller;
+ interrupt-controller;
+ };
+ };
+
+ i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ gpioext2: gpio@70 {
+ /* GPIO Expander 2 Mapping :
+ * - 0: USB_HUB_INTn
+ * - 1: HUB_CONNECT
+ * - 2: GPIO_IOT2_RESET (out active low / pull-up)
+ * - 3: GPIO_IOT1_RESET (out active low / pull-up)
+ * - 4: GPIO_IOT0_RESET (out active low / pull-up)
+ * - 5: TP901
+ * - 6: TP902
+ * - 7: TP903
+ * - 8: UART_EXP2_ENn (out active low / pull-down)
+ * - 9: PCM_EXP1_ENn (out active low)
+ * - 10: PCM_EXP1_SEL (out)
+ * - 11: ARD_FTDI
+ * - 12: TP904
+ * - 13: TP905
+ * - 14: TP906
+ * - 15: RS232_Enable (out active high / pull-up)
+ */
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "semtech,sx1509q";
+ reg = <0x70>;
+ interrupt-parent = <&gpioext1>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+
+ probe-reset;
+
+ gpio-controller;
+ interrupt-controller;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+&sdcc1 {
+ pinctrl-0 = <&sdc_cd_pins>;
+ pinctrl-names = "default";
+ disable-wp;
+ cd-gpios = <&msmgpio 42 GPIO_ACTIVE_LOW>; /* Active low CD */
+};
diff --git a/arch/arm/boot/dts/qcom-mdm9615-wp8548.dtsi b/arch/arm/boot/dts/qcom-mdm9615-wp8548.dtsi
new file mode 100644
index 000000000000..7869898e392d
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-mdm9615-wp8548.dtsi
@@ -0,0 +1,170 @@
+/*
+ * Device Tree Source for Sierra Wireless WP8548 Module
+ *
+ * Copyright (C) 2016 BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.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 "qcom-mdm9615.dtsi"
+
+/ {
+ model = "Sierra Wireless WP8548 Module";
+ compatible = "swir,wp8548", "qcom,mdm9615";
+
+ memory {
+ reg = <0x48000000 0x7F00000>;
+ };
+};
+
+&msmgpio {
+ pinctrl-0 = <&reset_out_pins>;
+ pinctrl-names = "default";
+
+ gsbi3_pins: gsbi3_pins {
+ mux {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ function = "gsbi3";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
+ gsbi4_pins: gsbi4_pins {
+ mux {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ function = "gsbi4";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
+ gsbi5_i2c_pins: gsbi5_i2c_pins {
+ pin16 {
+ pins = "gpio16";
+ function = "gsbi5_i2c";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ pin17 {
+ pins = "gpio17";
+ function = "gsbi5_i2c";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ gsbi5_uart_pins: gsbi5_uart_pins {
+ mux {
+ pins = "gpio18", "gpio19";
+ function = "gsbi5_uart";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
+ reset_out_pins: reset_out_pins {
+ pins {
+ pins = "gpio66";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ output-high;
+ };
+ };
+};
+
+&pmicgpio {
+ usb_vbus_5v_pins: usb_vbus_5v_pins {
+ pins = "gpio4";
+ function = "normal";
+ output-high;
+ bias-disable;
+ qcom,drive-strength = <1>;
+ power-source = <2>;
+ };
+};
+
+&gsbi3 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_SPI>;
+};
+
+&gsbi3_spi {
+ status = "ok";
+ pinctrl-0 = <&gsbi3_pins>;
+ pinctrl-names = "default";
+ assigned-clocks = <&gcc GSBI3_QUP_CLK>;
+ assigned-clock-rates = <24000000>;
+};
+
+&gsbi4 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_UART_W_FC>;
+};
+
+&gsbi4_serial {
+ status = "ok";
+ pinctrl-0 = <&gsbi4_pins>;
+ pinctrl-names = "default";
+};
+
+&gsbi5 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+};
+
+&gsbi5_i2c {
+ status = "ok";
+ clock-frequency = <200000>;
+ pinctrl-0 = <&gsbi5_i2c_pins>;
+ pinctrl-names = "default";
+};
+
+&gsbi5_serial {
+ status = "ok";
+ pinctrl-0 = <&gsbi5_uart_pins>;
+ pinctrl-names = "default";
+};
+
+&sdcc1 {
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi
new file mode 100644
index 000000000000..5ae4ec59e6ea
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi
@@ -0,0 +1,557 @@
+/*
+ * Device Tree Source for Qualcomm MDM9615 SoC
+ *
+ * Copyright (C) 2016 BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.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/ "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-mdm9615.h>
+#include <dt-bindings/reset/qcom,gcc-mdm9615.h>
+#include <dt-bindings/mfd/qcom-rpm.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+
+/ {
+ model = "Qualcomm MDM9615";
+ compatible = "qcom,mdm9615";
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a5";
+ device_type = "cpu";
+ next-level-cache = <&L2>;
+ };
+ };
+
+ cpu-pmu {
+ compatible = "arm,cortex-a5-pmu";
+ interrupts = <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ clocks {
+ cxo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ };
+ };
+
+ regulators {
+ vsdcc_fixed: vsdcc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "SDCC Power";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-always-on;
+ };
+ };
+
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ L2: l2-cache@2040000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x02040000 0x1000>;
+ arm,data-latency = <2 2 0>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ intc: interrupt-controller@2000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x02000000 0x1000>,
+ <0x02002000 0x1000>;
+ };
+
+ timer@200a000 {
+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
+ interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_EDGE_RISING)>,
+ <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_EDGE_RISING)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_EDGE_RISING)>;
+ reg = <0x0200a000 0x100>;
+ clock-frequency = <27000000>,
+ <32768>;
+ cpu-offset = <0x80000>;
+ };
+
+ msmgpio: pinctrl@800000 {
+ compatible = "qcom,mdm9615-pinctrl";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x800000 0x4000>;
+ };
+
+ gcc: clock-controller@900000 {
+ compatible = "qcom,gcc-mdm9615";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0x900000 0x4000>;
+ };
+
+ lcc: clock-controller@28000000 {
+ compatible = "qcom,lcc-mdm9615";
+ reg = <0x28000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ l2cc: clock-controller@2011000 {
+ compatible = "syscon";
+ reg = <0x02011000 0x1000>;
+ };
+
+ rng@1a500000 {
+ compatible = "qcom,prng";
+ reg = <0x1a500000 0x200>;
+ clocks = <&gcc PRNG_CLK>;
+ clock-names = "core";
+ assigned-clocks = <&gcc PRNG_CLK>;
+ assigned-clock-rates = <32000000>;
+ };
+
+ gsbi2: gsbi@16100000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <2>;
+ reg = <0x16100000 0x100>;
+ clocks = <&gcc GSBI2_H_CLK>;
+ clock-names = "iface";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gsbi2_i2c: i2c@16180000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x16180000 0x1000>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ gsbi3: gsbi@16200000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <3>;
+ reg = <0x16200000 0x100>;
+ clocks = <&gcc GSBI3_H_CLK>;
+ clock-names = "iface";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gsbi3_spi: spi@16280000 {
+ compatible = "qcom,spi-qup-v1.1.1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x16280000 0x1000>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ spi-max-frequency = <24000000>;
+
+ clocks = <&gcc GSBI3_QUP_CLK>, <&gcc GSBI3_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ gsbi4: gsbi@16300000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <4>;
+ reg = <0x16300000 0x100>;
+ clocks = <&gcc GSBI4_H_CLK>;
+ clock-names = "iface";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ gsbi4_serial: serial@16340000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x16340000 0x1000>,
+ <0x16300000 0x1000>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ gsbi5: gsbi@16400000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <5>;
+ reg = <0x16400000 0x100>;
+ clocks = <&gcc GSBI5_H_CLK>;
+ clock-names = "iface";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ syscon-tcsr = <&tcsr>;
+
+ gsbi5_i2c: i2c@16480000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x16480000 0x1000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+
+ /* QUP clock is not initialized, set rate */
+ assigned-clocks = <&gcc GSBI5_QUP_CLK>;
+ assigned-clock-rates = <24000000>;
+
+ clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+
+ gsbi5_serial: serial@16440000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x16440000 0x1000>,
+ <0x16400000 0x1000>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
+ qcom,ssbi@500000 {
+ compatible = "qcom,ssbi";
+ reg = <0x500000 0x1000>;
+ qcom,controller-type = "pmic-arbiter";
+
+ pmicintc: pmic@0 {
+ compatible = "qcom,pm8018", "qcom,pm8921";
+ interrupts = <GIC_PPI 226 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pwrkey@1c {
+ compatible = "qcom,pm8018-pwrkey", "qcom,pm8921-pwrkey";
+ reg = <0x1c>;
+ interrupt-parent = <&pmicintc>;
+ interrupts = <50 IRQ_TYPE_EDGE_RISING>,
+ <51 IRQ_TYPE_EDGE_RISING>;
+ debounce = <15625>;
+ pull-up;
+ };
+
+ pmicmpp: mpp@50 {
+ compatible = "qcom,pm8018-mpp", "qcom,ssbi-mpp";
+ interrupt-parent = <&pmicintc>;
+ interrupts = <24 IRQ_TYPE_NONE>,
+ <25 IRQ_TYPE_NONE>,
+ <26 IRQ_TYPE_NONE>,
+ <27 IRQ_TYPE_NONE>,
+ <28 IRQ_TYPE_NONE>,
+ <29 IRQ_TYPE_NONE>;
+ reg = <0x50>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc@11d {
+ compatible = "qcom,pm8018-rtc", "qcom,pm8921-rtc";
+ interrupt-parent = <&pmicintc>;
+ interrupts = <39 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x11d>;
+ allow-set-time;
+ };
+
+ pmicgpio: gpio@150 {
+ compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio";
+ interrupt-parent = <&pmicintc>;
+ interrupts = <24 IRQ_TYPE_NONE>,
+ <25 IRQ_TYPE_NONE>,
+ <26 IRQ_TYPE_NONE>,
+ <27 IRQ_TYPE_NONE>,
+ <28 IRQ_TYPE_NONE>,
+ <29 IRQ_TYPE_NONE>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+ };
+
+ sdcc1bam: dma@12182000{
+ compatible = "qcom,bam-v1.3.0";
+ reg = <0x12182000 0x8000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc SDC1_H_CLK>;
+ clock-names = "bam_clk";
+ #dma-cells = <1>;
+ qcom,ee = <0>;
+ };
+
+ sdcc2bam: dma@12142000{
+ compatible = "qcom,bam-v1.3.0";
+ reg = <0x12142000 0x8000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc SDC2_H_CLK>;
+ clock-names = "bam_clk";
+ #dma-cells = <1>;
+ qcom,ee = <0>;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ sdcc1: sdcc@12180000 {
+ status = "disabled";
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ reg = <0x12180000 0x2000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC1_CLK>, <&gcc SDC1_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <8>;
+ max-frequency = <48000000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ vmmc-supply = <&vsdcc_fixed>;
+ dmas = <&sdcc1bam 2>, <&sdcc1bam 1>;
+ dma-names = "tx", "rx";
+ assigned-clocks = <&gcc SDC1_CLK>;
+ assigned-clock-rates = <400000>;
+ };
+
+ sdcc2: sdcc@12140000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x00051180>;
+ status = "disabled";
+ reg = <0x12140000 0x2000>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&gcc SDC2_CLK>, <&gcc SDC2_H_CLK>;
+ clock-names = "mclk", "apb_pclk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <48000000>;
+ no-1-8-v;
+ vmmc-supply = <&vsdcc_fixed>;
+ dmas = <&sdcc2bam 2>, <&sdcc2bam 1>;
+ dma-names = "tx", "rx";
+ assigned-clocks = <&gcc SDC2_CLK>;
+ assigned-clock-rates = <400000>;
+ };
+ };
+
+ tcsr: syscon@1a400000 {
+ compatible = "qcom,tcsr-mdm9615", "syscon";
+ reg = <0x1a400000 0x100>;
+ };
+
+ rpm: rpm@108000 {
+ compatible = "qcom,rpm-mdm9615";
+ reg = <0x108000 0x1000>;
+
+ qcom,ipc = <&l2cc 0x8 2>;
+
+ interrupts = <GIC_SPI 19 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 22 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "ack", "err", "wakeup";
+
+ regulators {
+ compatible = "qcom,rpm-pm8018-regulators";
+
+ vin_lvs1-supply = <&pm8018_s3>;
+
+ vdd_l7-supply = <&pm8018_s4>;
+ vdd_l8-supply = <&pm8018_s3>;
+ vdd_l9_l10_l11_l12-supply = <&pm8018_s5>;
+
+ /* Buck SMPS */
+ pm8018_s1: s1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1150000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ };
+
+ pm8018_s2: s2 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1300000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ };
+
+ pm8018_s3: s3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ };
+
+ pm8018_s4: s4 {
+ regulator-min-microvolt = <2100000>;
+ regulator-max-microvolt = <2200000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ };
+
+ pm8018_s5: s5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ };
+
+ /* PMOS LDO */
+ pm8018_l2: l2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ bias-pull-down;
+ };
+
+ pm8018_l3: l3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ bias-pull-down;
+ };
+
+ pm8018_l4: l4 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ bias-pull-down;
+ };
+
+ pm8018_l5: l5 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ bias-pull-down;
+ };
+
+ pm8018_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2850000>;
+ bias-pull-down;
+ };
+
+ pm8018_l7: l7 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1900000>;
+ bias-pull-down;
+ };
+
+ pm8018_l8: l8 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ bias-pull-down;
+ };
+
+ pm8018_l9: l9 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1150000>;
+ bias-pull-down;
+ };
+
+ pm8018_l10: l10 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ bias-pull-down;
+ };
+
+ pm8018_l11: l11 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ bias-pull-down;
+ };
+
+ pm8018_l12: l12 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ bias-pull-down;
+ };
+
+ pm8018_l13: l13 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <2950000>;
+ bias-pull-down;
+ };
+
+ pm8018_l14: l14 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ bias-pull-down;
+ };
+
+ /* Low Voltage Switch */
+ pm8018_lvs1: lvs1 {
+ bias-pull-down;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
index 8c65e0d82559..4d828f810746 100644
--- a/arch/arm/boot/dts/qcom-msm8660.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
@@ -141,6 +141,23 @@
};
};
+ external-bus@1a100000 {
+ compatible = "qcom,msm8660-ebi2";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x1a800000 0x00800000>,
+ <1 0x0 0x1b000000 0x00800000>,
+ <2 0x0 0x1b800000 0x00800000>,
+ <3 0x0 0x1d000000 0x08000000>,
+ <4 0x0 0x1c800000 0x00800000>,
+ <5 0x0 0x1c000000 0x00800000>;
+ reg = <0x1a100000 0x1000>, <0x1a110000 0x1000>;
+ reg-names = "ebi2", "xmem";
+ clocks = <&gcc EBI2_2X_CLK>, <&gcc EBI2_CLK>;
+ clock-names = "ebi2x", "ebi2";
+ status = "disabled";
+ };
+
qcom,ssbi@500000 {
compatible = "qcom,ssbi";
reg = <0x500000 0x1000>;
diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
index c0fb4a698c56..382bcc3231a9 100644
--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
@@ -224,6 +224,35 @@
status = "ok";
};
+ pinctrl@fd510000 {
+ 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;
+ };
+ };
+ };
+
+ 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>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
input-name = "gpio-keys";
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index d2109475bdfd..49d579f28865 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -220,13 +220,13 @@
};
clocks {
- xo_board {
+ xo_board: xo_board {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <19200000>;
};
- sleep_clk {
+ sleep_clk: sleep_clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
@@ -558,8 +558,10 @@
reg-names = "hc_mem", "core_mem";
interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
- clock-names = "core", "iface";
+ clocks = <&gcc GCC_SDCC1_APPS_CLK>,
+ <&gcc GCC_SDCC1_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
status = "disabled";
};
@@ -569,8 +571,10 @@
reg-names = "hc_mem", "core_mem";
interrupts = <0 125 0>, <0 221 0>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
- clock-names = "core", "iface";
+ clocks = <&gcc GCC_SDCC2_APPS_CLK>,
+ <&gcc GCC_SDCC2_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/r7s72100-rskrza1.dts b/arch/arm/boot/dts/r7s72100-rskrza1.dts
index e5dea5bb4032..dd4418195ca6 100644
--- a/arch/arm/boot/dts/r7s72100-rskrza1.dts
+++ b/arch/arm/boot/dts/r7s72100-rskrza1.dts
@@ -56,6 +56,11 @@
};
};
+&sdhi1 {
+ bus-width = <4>;
+ status = "okay";
+};
+
&scif2 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
index fb9ef9ca120e..3dd427d68c83 100644
--- a/arch/arm/boot/dts/r7s72100.dtsi
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -117,6 +117,15 @@
clock-output-names = "ether";
};
+ mstp8_clks: mstp8_clks@fcfe0434 {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xfcfe0434 4>;
+ clocks = <&p1_clk>;
+ clock-indices = <R7S72100_CLK_MMCIF>;
+ clock-output-names = "mmcif";
+ };
+
mstp9_clks: mstp9_clks@fcfe0438 {
#clock-cells = <1>;
compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -140,6 +149,14 @@
>;
clock-output-names = "spi0", "spi1", "spi2", "spi3", "spi4";
};
+ mstp12_clks: mstp12_clks@fcfe0444 {
+ #clock-cells = <1>;
+ compatible = "renesas,r7s72100-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xfcfe0444 4>;
+ clocks = <&p1_clk>, <&p1_clk>;
+ clock-indices = <R7S72100_CLK_SDHI1 R7S72100_CLK_SDHI0>;
+ clock-output-names = "sdhi1", "sdhi0";
+ };
};
cpus {
@@ -441,4 +458,42 @@
#size-cells = <0>;
status = "disabled";
};
+
+ mmcif: mmc@e804c800 {
+ compatible = "renesas,mmcif-r7s72100", "renesas,sh-mmcif";
+ reg = <0xe804c800 0x80>;
+ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R7S72100_CLK_MMCIF>;
+ reg-io-width = <4>;
+ bus-width = <8>;
+ status = "disabled";
+ };
+
+ sdhi0: sd@e804e000 {
+ compatible = "renesas,sdhi-r7s72100";
+ reg = <0xe804e000 0x100>;
+ interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&mstp12_clks R7S72100_CLK_SDHI0>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
+
+ sdhi1: sd@e804e800 {
+ compatible = "renesas,sdhi-r7s72100";
+ reg = <0xe804e800 0x100>;
+ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&mstp12_clks R7S72100_CLK_SDHI1>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
index ca8672778fe0..53183ffe04c1 100644
--- a/arch/arm/boot/dts/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/r8a73a4.dtsi
@@ -751,6 +751,11 @@
};
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,sysc-r8a73a4", "renesas,sysc-rmobile";
reg = <0 0xe6180000 0 0x8000>, <0 0xe6188000 0 0x8000>;
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index 159e04eb1b9e..34159a8349de 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -8,8 +8,6 @@
* kind, whether express or implied.
*/
-/include/ "skeleton.dtsi"
-
#include <dt-bindings/clock/r8a7740-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
@@ -17,6 +15,8 @@
/ {
compatible = "renesas,r8a7740";
interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
cpus {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts b/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
new file mode 100644
index 000000000000..3a22538208f2
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
@@ -0,0 +1,57 @@
+/*
+ * Device Tree Source for the SK-RZG1M board
+ *
+ * Copyright (C) 2016 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 "r8a7743.dtsi"
+
+/ {
+ model = "SK-RZG1M";
+ compatible = "renesas,sk-rzg1m", "renesas,r8a7743";
+
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+
+ memory@200000000 {
+ device_type = "memory";
+ reg = <2 0x00000000 0 0x40000000>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&scif0 {
+ status = "okay";
+};
+
+&ether {
+ phy-handle = <&phy1>;
+ renesas,ether-link-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
new file mode 100644
index 000000000000..216cb1f37f87
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7743.dtsi
@@ -0,0 +1,476 @@
+/*
+ * Device Tree Source for the r8a7743 SoC
+ *
+ * Copyright (C) 2016 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.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r8a7743-cpg-mssr.h>
+#include <dt-bindings/power/r8a7743-sysc.h>
+
+/ {
+ compatible = "renesas,r8a7743";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ clock-frequency = <1500000000>;
+ clocks = <&cpg CPG_CORE R8A7743_CLK_Z>;
+ power-domains = <&sysc R8A7743_PD_CA15_CPU0>;
+ next-level-cache = <&L2_CA15>;
+ };
+
+ L2_CA15: cache-controller@0 {
+ compatible = "cache";
+ reg = <0>;
+ cache-unified;
+ cache-level = <2>;
+ power-domains = <&sysc R8A7743_PD_CA15_SCU>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@f1001000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0xf1001000 0 0x1000>,
+ <0 0xf1002000 0 0x1000>,
+ <0 0xf1004000 0 0x2000>,
+ <0 0xf1006000 0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ irqc: interrupt-controller@e61c0000 {
+ compatible = "renesas,irqc-r8a7743", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 407>;
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a7743-cpg-mssr";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>, <&usb_extal_clk>;
+ clock-names = "extal", "usb_extal";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,r8a7743-sysc";
+ reg = <0 0xe6180000 0 0x200>;
+ #power-domain-cells = <1>;
+ };
+
+ rst: reset-controller@e6160000 {
+ compatible = "renesas,r8a7743-rst";
+ reg = <0 0xe6160000 0 0x100>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,dmac-r8a7743",
+ "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x20000>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&cpg CPG_MOD 219>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ dmac1: dma-controller@e6720000 {
+ compatible = "renesas,dmac-r8a7743",
+ "renesas,rcar-dmac";
+ reg = <0 0xe6720000 0 0x20000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&cpg CPG_MOD 218>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7743",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c40000 0 0x40>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 204>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+ <&dmac1 0x21>, <&dmac1 0x22>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7743",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c50000 0 0x40>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 203>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+ <&dmac1 0x25>, <&dmac1 0x26>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7743",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c60000 0 0x40>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 202>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+ <&dmac1 0x27>, <&dmac1 0x28>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-r8a7743",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c70000 0 0x40>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1106>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+ <&dmac1 0x1b>, <&dmac1 0x1c>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c78000 {
+ compatible = "renesas,scifa-r8a7743",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c78000 0 0x40>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1107>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+ <&dmac1 0x1f>, <&dmac1 0x20>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa5: serial@e6c80000 {
+ compatible = "renesas,scifa-r8a7743",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c80000 0 0x40>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1108>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+ <&dmac1 0x23>, <&dmac1 0x24>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a7743",
+ "renesas,rcar-gen2-scifb", "renesas,scifb";
+ reg = <0 0xe6c20000 0 0x100>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 206>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+ <&dmac1 0x3d>, <&dmac1 0x3e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7743",
+ "renesas,rcar-gen2-scifb", "renesas,scifb";
+ reg = <0 0xe6c30000 0 0x100>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 207>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+ <&dmac1 0x19>, <&dmac1 0x1a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a7743",
+ "renesas,rcar-gen2-scifb", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 0x100>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 216>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+ <&dmac1 0x1d>, <&dmac1 0x1e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a7743",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6e60000 0 0x40>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 721>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+ <&dmac1 0x29>, <&dmac1 0x2a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a7743",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6e68000 0 0x40>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 720>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+ <&dmac1 0x2d>, <&dmac1 0x2e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif2: serial@e6e58000 {
+ compatible = "renesas,scif-r8a7743",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6e58000 0 0x40>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 719>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+ <&dmac1 0x2b>, <&dmac1 0x2c>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif3: serial@e6ea8000 {
+ compatible = "renesas,scif-r8a7743",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6ea8000 0 0x40>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 718>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+ <&dmac1 0x2f>, <&dmac1 0x30>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif4: serial@e6ee0000 {
+ compatible = "renesas,scif-r8a7743",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6ee0000 0 0x40>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 715>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+ <&dmac1 0xfb>, <&dmac1 0xfc>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif5: serial@e6ee8000 {
+ compatible = "renesas,scif-r8a7743",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6ee8000 0 0x40>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 714>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+ <&dmac1 0xfd>, <&dmac1 0xfe>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ hscif0: serial@e62c0000 {
+ compatible = "renesas,hscif-r8a7743",
+ "renesas,rcar-gen2-hscif", "renesas,hscif";
+ reg = <0 0xe62c0000 0 0x60>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 717>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+ <&dmac1 0x39>, <&dmac1 0x3a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ hscif1: serial@e62c8000 {
+ compatible = "renesas,hscif-r8a7743",
+ "renesas,rcar-gen2-hscif", "renesas,hscif";
+ reg = <0 0xe62c8000 0 0x60>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 716>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+ <&dmac1 0x4d>, <&dmac1 0x4e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ hscif2: serial@e62d0000 {
+ compatible = "renesas,hscif-r8a7743",
+ "renesas,rcar-gen2-hscif", "renesas,hscif";
+ reg = <0 0xe62d0000 0 0x60>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 713>,
+ <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+ <&dmac1 0x3b>, <&dmac1 0x3c>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ ether: ethernet@ee700000 {
+ compatible = "renesas,ether-r8a7743";
+ reg = <0 0xee700000 0 0x400>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 813>;
+ power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ /* External root clock */
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ /* External USB clock - can be overridden by the board */
+ usb_extal_clk: usb_extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ };
+
+ /* External SCIF clock */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts b/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
new file mode 100644
index 000000000000..97840b340197
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
@@ -0,0 +1,52 @@
+/*
+ * Device Tree Source for the SK-RZG1E board
+ *
+ * Copyright (C) 2016 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 "r8a7745.dtsi"
+
+/ {
+ model = "SK-RZG1E";
+ compatible = "renesas,sk-rzg1e", "renesas,r8a7745";
+
+ aliases {
+ serial0 = &scif2;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x40000000>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <20000000>;
+};
+
+&scif2 {
+ status = "okay";
+};
+
+&ether {
+ phy-handle = <&phy1>;
+ renesas,ether-link-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi
new file mode 100644
index 000000000000..0b2e2f37150f
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7745.dtsi
@@ -0,0 +1,476 @@
+/*
+ * Device Tree Source for the r8a7745 SoC
+ *
+ * Copyright (C) 2016 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.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r8a7745-cpg-mssr.h>
+#include <dt-bindings/power/r8a7745-sysc.h>
+
+/ {
+ compatible = "renesas,r8a7745";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0>;
+ clock-frequency = <1000000000>;
+ clocks = <&cpg CPG_CORE R8A7745_CLK_Z2>;
+ power-domains = <&sysc R8A7745_PD_CA7_CPU0>;
+ next-level-cache = <&L2_CA7>;
+ };
+
+ L2_CA7: cache-controller@0 {
+ compatible = "cache";
+ reg = <0>;
+ cache-unified;
+ cache-level = <2>;
+ power-domains = <&sysc R8A7745_PD_CA7_SCU>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@f1001000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0xf1001000 0 0x1000>,
+ <0 0xf1002000 0 0x1000>,
+ <0 0xf1004000 0 0x2000>,
+ <0 0xf1006000 0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ irqc: interrupt-controller@e61c0000 {
+ compatible = "renesas,irqc-r8a7745", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 407>;
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a7745-cpg-mssr";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>, <&usb_extal_clk>;
+ clock-names = "extal", "usb_extal";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,r8a7745-sysc";
+ reg = <0 0xe6180000 0 0x200>;
+ #power-domain-cells = <1>;
+ };
+
+ rst: reset-controller@e6160000 {
+ compatible = "renesas,r8a7745-rst";
+ reg = <0 0xe6160000 0 0x100>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,dmac-r8a7745",
+ "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x20000>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&cpg CPG_MOD 219>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ dmac1: dma-controller@e6720000 {
+ compatible = "renesas,dmac-r8a7745",
+ "renesas,rcar-dmac";
+ reg = <0 0xe6720000 0 0x20000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14";
+ clocks = <&cpg CPG_MOD 218>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7745",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c40000 0 0x40>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 204>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+ <&dmac1 0x21>, <&dmac1 0x22>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7745",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c50000 0 0x40>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 203>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+ <&dmac1 0x25>, <&dmac1 0x26>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7745",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c60000 0 0x40>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 202>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+ <&dmac1 0x27>, <&dmac1 0x28>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-r8a7745",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c70000 0 0x40>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1106>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+ <&dmac1 0x1b>, <&dmac1 0x1c>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c78000 {
+ compatible = "renesas,scifa-r8a7745",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c78000 0 0x40>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1107>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+ <&dmac1 0x1f>, <&dmac1 0x20>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifa5: serial@e6c80000 {
+ compatible = "renesas,scifa-r8a7745",
+ "renesas,rcar-gen2-scifa", "renesas,scifa";
+ reg = <0 0xe6c80000 0 0x40>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 1108>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+ <&dmac1 0x23>, <&dmac1 0x24>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a7745",
+ "renesas,rcar-gen2-scifb", "renesas,scifb";
+ reg = <0 0xe6c20000 0 0x100>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 206>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+ <&dmac1 0x3d>, <&dmac1 0x3e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7745",
+ "renesas,rcar-gen2-scifb", "renesas,scifb";
+ reg = <0 0xe6c30000 0 0x100>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 207>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+ <&dmac1 0x19>, <&dmac1 0x1a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a7745",
+ "renesas,rcar-gen2-scifb", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 0x100>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 216>;
+ clock-names = "fck";
+ dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+ <&dmac1 0x1d>, <&dmac1 0x1e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a7745",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6e60000 0 0x40>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 721>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+ <&dmac1 0x29>, <&dmac1 0x2a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a7745",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6e68000 0 0x40>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 720>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+ <&dmac1 0x2d>, <&dmac1 0x2e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif2: serial@e6e58000 {
+ compatible = "renesas,scif-r8a7745",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6e58000 0 0x40>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 719>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+ <&dmac1 0x2b>, <&dmac1 0x2c>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif3: serial@e6ea8000 {
+ compatible = "renesas,scif-r8a7745",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6ea8000 0 0x40>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 718>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+ <&dmac1 0x2f>, <&dmac1 0x30>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif4: serial@e6ee0000 {
+ compatible = "renesas,scif-r8a7745",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6ee0000 0 0x40>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 715>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+ <&dmac1 0xfb>, <&dmac1 0xfc>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ scif5: serial@e6ee8000 {
+ compatible = "renesas,scif-r8a7745",
+ "renesas,rcar-gen2-scif", "renesas,scif";
+ reg = <0 0xe6ee8000 0 0x40>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 714>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+ <&dmac1 0xfd>, <&dmac1 0xfe>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ hscif0: serial@e62c0000 {
+ compatible = "renesas,hscif-r8a7745",
+ "renesas,rcar-gen2-hscif", "renesas,hscif";
+ reg = <0 0xe62c0000 0 0x60>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 717>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+ <&dmac1 0x39>, <&dmac1 0x3a>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ hscif1: serial@e62c8000 {
+ compatible = "renesas,hscif-r8a7745",
+ "renesas,rcar-gen2-hscif", "renesas,hscif";
+ reg = <0 0xe62c8000 0 0x60>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 716>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+ <&dmac1 0x4d>, <&dmac1 0x4e>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ hscif2: serial@e62d0000 {
+ compatible = "renesas,hscif-r8a7745",
+ "renesas,rcar-gen2-hscif", "renesas,hscif";
+ reg = <0 0xe62d0000 0 0x60>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 713>,
+ <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+ <&dmac1 0x3b>, <&dmac1 0x3c>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ ether: ethernet@ee700000 {
+ compatible = "renesas,ether-r8a7745";
+ reg = <0 0xee700000 0 0x400>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 813>;
+ power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+ phy-mode = "rmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ /* External root clock */
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ /* External USB clock - can be overridden by the board */
+ usb_extal_clk: usb_extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <48000000>;
+ };
+
+ /* External SCIF clock */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi
index 3d0a18abd408..d0db998effc8 100644
--- a/arch/arm/boot/dts/r8a7778.dtsi
+++ b/arch/arm/boot/dts/r8a7778.dtsi
@@ -14,8 +14,6 @@
* kind, whether express or implied.
*/
-/include/ "skeleton.dtsi"
-
#include <dt-bindings/clock/r8a7778-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
@@ -23,6 +21,8 @@
/ {
compatible = "renesas,r8a7778";
interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
cpus {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts
index 541678df90a9..676151b70185 100644
--- a/arch/arm/boot/dts/r8a7779-marzen.dts
+++ b/arch/arm/boot/dts/r8a7779-marzen.dts
@@ -170,7 +170,7 @@
du_pins: du {
du0 {
- groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0";
+ groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0", "du0_clk_in";
function = "du0";
};
du1 {
diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index 8cf16008a09b..55a7c1e37c57 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -9,8 +9,6 @@
* kind, whether express or implied.
*/
-/include/ "skeleton.dtsi"
-
#include <dt-bindings/clock/r8a7779-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
@@ -19,6 +17,8 @@
/ {
compatible = "renesas,r8a7779";
interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
cpus {
#address-cells = <1>;
@@ -420,7 +420,7 @@
du: display@fff80000 {
compatible = "renesas,du-r8a7779";
- reg = <0 0xfff80000 0 0x40000>;
+ reg = <0xfff80000 0x40000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7779_CLK_DU>;
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
@@ -590,6 +590,11 @@
};
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0xff000044 4>;
+ };
+
rst: reset-controller@ffcc0000 {
compatible = "renesas,r8a7779-reset-wdt";
reg = <0xffcc0000 0x48>;
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 52b56fcaddf2..bd512c86e852 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -50,7 +50,9 @@
aliases {
serial0 = &scif0;
serial1 = &scifa1;
- i2c8 = "i2cexio";
+ i2c8 = &gpioi2c1;
+ i2c10 = &i2cexio0;
+ i2c11 = &i2cexio1;
};
chosen {
@@ -231,12 +233,23 @@
};
};
+ hdmi-in {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&adv7612_in>;
+ };
+ };
+ };
+
hdmi-out {
compatible = "hdmi-connector";
type = "a";
port {
- hdmi_con: endpoint {
+ hdmi_con_out: endpoint {
remote-endpoint = <&adv7511_out>;
};
};
@@ -254,6 +267,17 @@
clock-frequency = <148500000>;
};
+ gpioi2c1: i2c-8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "i2c-gpio";
+ status = "disabled";
+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH /* sda */
+ &gpio1 16 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,delay-us = <5>;
+ };
+
/*
* IIC0/I2C0 is routed to EXIO connector A, pins 114 (SCL) + 116 (SDA) only.
* We use the I2C demuxer, so the desired IP core can be selected at runtime
@@ -262,11 +286,26 @@
* bus with IIC3 on pins 110 (SCL) + 112 (SDA), select I2C0 at runtime, and
* instantiate the slave device at runtime according to the documentation.
* You can then communicate with the slave via IIC3.
+ *
+ * IIC0/I2C0 does not appear to support fallback to GPIO.
*/
- i2cexio: i2c-8 {
+ i2cexio0: i2c-10 {
compatible = "i2c-demux-pinctrl";
i2c-parent = <&iic0>, <&i2c0>;
- i2c-bus-name = "i2c-exio";
+ i2c-bus-name = "i2c-exio0";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ /*
+ * IIC1/I2C1 is routed to EXIO connector A, pins 78 (SCL) + 80 (SDA).
+ * This is similar to the arangement described for i2cexio0 (above)
+ * with a fallback to GPIO also provided.
+ */
+ i2cexio1: i2c-11 {
+ compatible = "i2c-demux-pinctrl";
+ i2c-parent = <&iic1>, <&i2c1>, <&gpioi2c1>;
+ i2c-bus-name = "i2c-exio1";
#address-cells = <1>;
#size-cells = <0>;
};
@@ -392,6 +431,11 @@
function = "iic0";
};
+ i2c1_pins: i2c1 {
+ groups = "i2c1";
+ function = "i2c1";
+ };
+
iic1_pins: iic1 {
groups = "iic1";
function = "iic1";
@@ -427,6 +471,11 @@
function = "usb2";
};
+ vin0_pins: vin0 {
+ groups = "vin0_data24", "vin0_sync", "vin0_clkenb", "vin0_clk";
+ function = "vin0";
+ };
+
vin1_pins: vin1 {
groups = "vin1_data8", "vin1_clk";
function = "vin1";
@@ -559,6 +608,7 @@
vqmmc-supply = <&vccq_sdhi0>;
cd-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
sd-uhs-sdr50;
+ sd-uhs-sdr104;
status = "okay";
};
@@ -580,18 +630,22 @@
&i2c0 {
pinctrl-0 = <&i2c0_pins>;
- pinctrl-names = "i2c-exio";
+ pinctrl-names = "i2c-exio0";
};
&iic0 {
pinctrl-0 = <&iic0_pins>;
- pinctrl-names = "i2c-exio";
+ pinctrl-names = "i2c-exio0";
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "i2c-exio1";
};
&iic1 {
- status = "okay";
pinctrl-0 = <&iic1_pins>;
- pinctrl-names = "default";
+ pinctrl-names = "i2c-exio1";
};
&iic2 {
@@ -646,7 +700,34 @@
port@1 {
reg = <1>;
adv7511_out: endpoint {
- remote-endpoint = <&hdmi_con>;
+ remote-endpoint = <&hdmi_con_out>;
+ };
+ };
+ };
+ };
+
+ hdmi-in@4c {
+ compatible = "adi,adv7612";
+ reg = <0x4c>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+ default-input = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7612_in: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ adv7612_out: endpoint {
+ remote-endpoint = <&vin0ep2>;
};
};
};
@@ -722,6 +803,25 @@
status = "okay";
};
+/* HDMI video input */
+&vin0 {
+ pinctrl-0 = <&vin0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ port {
+ vin0ep2: endpoint {
+ remote-endpoint = <&adv7612_out>;
+ bus-width = <24>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pclk-sample = <1>;
+ data-active = <1>;
+ };
+ };
+};
+
/* composite video input */
&vin1 {
pinctrl-0 = <&vin1_pins>;
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 3f10b0bf1b08..0c8900d4b824 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -711,7 +711,7 @@
scifb0: serial@e6c20000 {
compatible = "renesas,scifb-r8a7790",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c20000 0 64>;
+ reg = <0 0xe6c20000 0 0x100>;
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>;
clock-names = "fck";
@@ -725,7 +725,7 @@
scifb1: serial@e6c30000 {
compatible = "renesas,scifb-r8a7790",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c30000 0 64>;
+ reg = <0 0xe6c30000 0 0x100>;
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>;
clock-names = "fck";
@@ -739,7 +739,7 @@
scifb2: serial@e6ce0000 {
compatible = "renesas,scifb-r8a7790",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6ce0000 0 64>;
+ reg = <0 0xe6ce0000 0 0x100>;
interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>;
clock-names = "fck";
@@ -1471,6 +1471,11 @@
};
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
+
rst: reset-controller@e6160000 {
compatible = "renesas,r8a7790-rst";
reg = <0 0xe6160000 0 0x0100>;
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index f8a7d090fd01..5405d337d744 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -50,6 +50,8 @@
aliases {
serial0 = &scif0;
serial1 = &scif1;
+ i2c9 = &gpioi2c1;
+ i2c12 = &i2cexio1;
};
chosen {
@@ -265,12 +267,23 @@
};
};
+ hdmi-in {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&adv7612_in>;
+ };
+ };
+ };
+
hdmi-out {
compatible = "hdmi-connector";
type = "a";
port {
- hdmi_con: endpoint {
+ hdmi_con_out: endpoint {
remote-endpoint = <&adv7511_out>;
};
};
@@ -287,6 +300,29 @@
#clock-cells = <0>;
clock-frequency = <148500000>;
};
+
+ gpioi2c1: i2c-9 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "i2c-gpio";
+ status = "disabled";
+ gpios = <&gpio7 16 GPIO_ACTIVE_HIGH /* sda */
+ &gpio7 15 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,delay-us = <5>;
+ };
+
+ /*
+ * I2C1 is routed to EXIO connector B, pins 64 (SCL) + 66 (SDA).
+ * A fallback to GPIO is provided.
+ */
+ i2cexio1: i2c-12 {
+ compatible = "i2c-demux-pinctrl";
+ i2c-parent = <&i2c1>, <&gpioi2c1>;
+ i2c-bus-name = "i2c-exio1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
&du {
@@ -322,6 +358,11 @@
pinctrl-0 = <&scif_clk_pins>;
pinctrl-names = "default";
+ i2c1_pins: i2c1 {
+ groups = "i2c1";
+ function = "i2c1";
+ };
+
i2c2_pins: i2c2 {
groups = "i2c2";
function = "i2c2";
@@ -360,16 +401,37 @@
sdhi0_pins: sd0 {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
};
sdhi1_pins: sd1 {
groups = "sdhi1_data4", "sdhi1_ctrl";
function = "sdhi1";
+ power-source = <3300>;
+ };
+
+ sdhi1_pins_uhs: sd1_uhs {
+ groups = "sdhi1_data4", "sdhi1_ctrl";
+ function = "sdhi1";
+ power-source = <1800>;
};
sdhi2_pins: sd2 {
groups = "sdhi2_data4", "sdhi2_ctrl";
function = "sdhi2";
+ power-source = <3300>;
+ };
+
+ sdhi2_pins_uhs: sd2_uhs {
+ groups = "sdhi2_data4", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <1800>;
};
qspi_pins: qspi {
@@ -393,6 +455,11 @@
function = "usb1";
};
+ vin0_pins: vin0 {
+ groups = "vin0_data24", "vin0_sync", "vin0_clkenb", "vin0_clk";
+ function = "vin0";
+ };
+
vin1_pins: vin1 {
groups = "vin1_data8", "vin1_clk";
function = "vin1";
@@ -454,33 +521,40 @@
&sdhi0 {
pinctrl-0 = <&sdhi0_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi0>;
vqmmc-supply = <&vccq_sdhi0>;
cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
status = "okay";
};
&sdhi1 {
pinctrl-0 = <&sdhi1_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi1_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi1>;
vqmmc-supply = <&vccq_sdhi1>;
cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+ sd-uhs-sdr50;
status = "okay";
};
&sdhi2 {
pinctrl-0 = <&sdhi2_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi2_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi2>;
vqmmc-supply = <&vccq_sdhi2>;
cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>;
+ sd-uhs-sdr50;
status = "okay";
};
@@ -538,6 +612,11 @@
};
};
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "i2c-exio1";
+};
+
&i2c2 {
pinctrl-0 = <&i2c2_pins>;
pinctrl-names = "default";
@@ -590,7 +669,34 @@
port@1 {
reg = <1>;
adv7511_out: endpoint {
- remote-endpoint = <&hdmi_con>;
+ remote-endpoint = <&hdmi_con_out>;
+ };
+ };
+ };
+ };
+
+ hdmi-in@4c {
+ compatible = "adi,adv7612";
+ reg = <0x4c>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ default-input = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7612_in: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ adv7612_out: endpoint {
+ remote-endpoint = <&vin0ep2>;
};
};
};
@@ -672,6 +778,27 @@
cpu0-supply = <&vdd_dvfs>;
};
+/* HDMI video input */
+&vin0 {
+ status = "okay";
+ pinctrl-0 = <&vin0_pins>;
+ pinctrl-names = "default";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vin0ep2: endpoint {
+ remote-endpoint = <&adv7612_out>;
+ bus-width = <24>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pclk-sample = <1>;
+ data-active = <1>;
+ };
+ };
+};
+
/* composite video input */
&vin1 {
status = "okay";
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index c465c79bcca6..87214668d70f 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -584,6 +584,7 @@
dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
<&dmac1 0xcd>, <&dmac1 0xce>;
dma-names = "tx", "rx", "tx", "rx";
+ max-frequency = <195000000>;
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -596,6 +597,7 @@
dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
<&dmac1 0xc1>, <&dmac1 0xc2>;
dma-names = "tx", "rx", "tx", "rx";
+ max-frequency = <97500000>;
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -608,6 +610,7 @@
dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
<&dmac1 0xd3>, <&dmac1 0xd4>;
dma-names = "tx", "rx", "tx", "rx";
+ max-frequency = <97500000>;
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -699,7 +702,7 @@
scifb0: serial@e6c20000 {
compatible = "renesas,scifb-r8a7791",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c20000 0 64>;
+ reg = <0 0xe6c20000 0 0x100>;
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>;
clock-names = "fck";
@@ -713,7 +716,7 @@
scifb1: serial@e6c30000 {
compatible = "renesas,scifb-r8a7791",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c30000 0 64>;
+ reg = <0 0xe6c30000 0 0x100>;
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>;
clock-names = "fck";
@@ -727,7 +730,7 @@
scifb2: serial@e6ce0000 {
compatible = "renesas,scifb-r8a7791",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6ce0000 0 64>;
+ reg = <0 0xe6ce0000 0 0x100>;
interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>;
clock-names = "fck";
@@ -1487,6 +1490,11 @@
reg = <0 0xe6160000 0 0x0100>;
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,r8a7791-sysc";
reg = <0 0xe6180000 0 0x0200>;
diff --git a/arch/arm/boot/dts/r8a7792-wheat.dts b/arch/arm/boot/dts/r8a7792-wheat.dts
index 6dbb94114a93..c24f26fdab1f 100644
--- a/arch/arm/boot/dts/r8a7792-wheat.dts
+++ b/arch/arm/boot/dts/r8a7792-wheat.dts
@@ -86,6 +86,34 @@
gpio = <&gpio11 12 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ hdmi-out0 {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con0: endpoint {
+ remote-endpoint = <&adv7513_0_out>;
+ };
+ };
+ };
+
+ hdmi-out1 {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con1: endpoint {
+ remote-endpoint = <&adv7513_1_out>;
+ };
+ };
+ };
+
+ osc2_clk: osc2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <74250000>;
+ };
};
&extal_clk {
@@ -128,6 +156,16 @@
groups = "qspi_ctrl", "qspi_data4";
function = "qspi";
};
+
+ du0_pins: du0 {
+ groups = "du0_rgb888", "du0_sync", "du0_disp";
+ function = "du0";
+ };
+
+ du1_pins: du1 {
+ groups = "du1_rgb666", "du1_sync", "du1_disp";
+ function = "du1";
+ };
};
&scif0 {
@@ -197,3 +235,91 @@
};
};
};
+
+&i2c4 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ hdmi@3d {
+ compatible = "adi,adv7513";
+ reg = <0x3d>;
+
+ adi,input-depth = <8>;
+ adi,input-colorspace = "rgb";
+ adi,input-clock = "1x";
+ adi,input-style = <1>;
+ adi,input-justification = "evenly";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7513_0_in: endpoint {
+ remote-endpoint = <&du_out_rgb0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7513_0_out: endpoint {
+ remote-endpoint = <&hdmi_con0>;
+ };
+ };
+ };
+ };
+
+ hdmi@39 {
+ compatible = "adi,adv7513";
+ reg = <0x39>;
+
+ adi,input-depth = <8>;
+ adi,input-colorspace = "rgb";
+ adi,input-clock = "1x";
+ adi,input-style = <1>;
+ adi,input-justification = "evenly";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7513_1_in: endpoint {
+ remote-endpoint = <&du_out_rgb1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7513_1_out: endpoint {
+ remote-endpoint = <&hdmi_con1>;
+ };
+ };
+ };
+ };
+};
+
+&du {
+ pinctrl-0 = <&du0_pins &du1_pins>;
+ pinctrl-names = "default";
+
+ clocks = <&mstp7_clks R8A7792_CLK_DU0>, <&mstp7_clks R8A7792_CLK_DU1>,
+ <&osc2_clk>;
+ clock-names = "du.0", "du.1", "dclkin.0";
+ status = "okay";
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <&adv7513_0_in>;
+ };
+ };
+ port@1 {
+ endpoint {
+ remote-endpoint = <&adv7513_1_in>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi
index 6e1f61f65d29..6ced3c1ec377 100644
--- a/arch/arm/boot/dts/r8a7792.dtsi
+++ b/arch/arm/boot/dts/r8a7792.dtsi
@@ -26,6 +26,8 @@
i2c4 = &i2c4;
i2c5 = &i2c5;
spi0 = &qspi;
+ spi1 = &msiof0;
+ spi2 = &msiof1;
vin0 = &vin0;
vin1 = &vin1;
vin2 = &vin2;
@@ -123,6 +125,11 @@
reg = <0 0xe6160000 0 0x0100>;
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,r8a7792-sysc";
reg = <0 0xe6180000 0 0x0200>;
@@ -577,6 +584,34 @@
status = "disabled";
};
+ msiof0: spi@e6e20000 {
+ compatible = "renesas,msiof-r8a7792";
+ reg = <0 0xe6e20000 0 0x0064>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks R8A7792_CLK_MSIOF0>;
+ dmas = <&dmac0 0x51>, <&dmac0 0x52>,
+ <&dmac1 0x51>, <&dmac1 0x52>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof1: spi@e6e10000 {
+ compatible = "renesas,msiof-r8a7792";
+ reg = <0 0xe6e10000 0 0x0064>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7792_CLK_MSIOF1>;
+ dmas = <&dmac0 0x55>, <&dmac0 0x56>,
+ <&dmac1 0x55>, <&dmac1 0x56>;
+ dma-names = "tx", "rx", "tx", "rx";
+ power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
du: display@feb00000 {
compatible = "renesas,du-r8a7792";
reg = <0 0xfeb00000 0 0x40000>;
@@ -768,6 +803,13 @@
clock-div = <48>;
clock-mult = <1>;
};
+ mp_clk: mp {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <15>;
+ clock-mult = <1>;
+ };
m2_clk: m2 {
compatible = "fixed-factor-clock";
clocks = <&cpg_clocks R8A7792_CLK_PLL1>;
@@ -798,6 +840,15 @@
};
/* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,r8a7792-mstp-clocks",
+ "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+ clocks = <&mp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <R8A7792_CLK_MSIOF0>;
+ clock-output-names = "msiof0";
+ };
mstp1_clks: mstp1_clks@e6150134 {
compatible = "renesas,r8a7792-mstp-clocks",
"renesas,cpg-mstp-clocks";
@@ -816,12 +867,13 @@
compatible = "renesas,r8a7792-mstp-clocks",
"renesas,cpg-mstp-clocks";
reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
- clocks = <&zs_clk>, <&zs_clk>;
+ clocks = <&mp_clk>, <&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
clock-indices = <
+ R8A7792_CLK_MSIOF1
R8A7792_CLK_SYS_DMAC1 R8A7792_CLK_SYS_DMAC0
>;
- clock-output-names = "sys-dmac1", "sys-dmac0";
+ clock-output-names = "msiof1", "sys-dmac1", "sys-dmac0";
};
mstp3_clks: mstp3_clks@e615013c {
compatible = "renesas,r8a7792-mstp-clocks",
diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts
index 90af18600124..dc311eba4444 100644
--- a/arch/arm/boot/dts/r8a7793-gose.dts
+++ b/arch/arm/boot/dts/r8a7793-gose.dts
@@ -346,18 +346,18 @@
};
sdhi0_pins: sd0 {
- renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
- renesas,function = "sdhi0";
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
};
sdhi1_pins: sd1 {
- renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
- renesas,function = "sdhi1";
+ groups = "sdhi1_data4", "sdhi1_ctrl";
+ function = "sdhi1";
};
sdhi2_pins: sd2 {
- renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
- renesas,function = "sdhi2";
+ groups = "sdhi2_data4", "sdhi2_ctrl";
+ function = "sdhi2";
};
qspi_pins: qspi {
diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index e4b385eccf74..2fb527ca0b15 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -666,7 +666,7 @@
scifb0: serial@e6c20000 {
compatible = "renesas,scifb-r8a7793",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c20000 0 64>;
+ reg = <0 0xe6c20000 0 0x100>;
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>;
clock-names = "fck";
@@ -680,7 +680,7 @@
scifb1: serial@e6c30000 {
compatible = "renesas,scifb-r8a7793",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c30000 0 64>;
+ reg = <0 0xe6c30000 0 0x100>;
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>;
clock-names = "fck";
@@ -694,7 +694,7 @@
scifb2: serial@e6ce0000 {
compatible = "renesas,scifb-r8a7793",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6ce0000 0 64>;
+ reg = <0 0xe6ce0000 0 0x100>;
interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>;
clock-names = "fck";
@@ -852,6 +852,33 @@
status = "disabled";
};
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a7793", "renesas,rcar-gen2-vin";
+ reg = <0 0xe6ef0000 0 0x1000>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7793_CLK_VIN0>;
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ vin1: video@e6ef1000 {
+ compatible = "renesas,vin-r8a7793", "renesas,rcar-gen2-vin";
+ reg = <0 0xe6ef1000 0 0x1000>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7793_CLK_VIN1>;
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ vin2: video@e6ef2000 {
+ compatible = "renesas,vin-r8a7793", "renesas,rcar-gen2-vin";
+ reg = <0 0xe6ef2000 0 0x1000>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7793_CLK_VIN2>;
+ power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
qspi: spi@e6b10000 {
compatible = "renesas,qspi-r8a7793", "renesas,qspi";
reg = <0 0xe6b10000 0 0x2c>;
@@ -1284,6 +1311,11 @@
reg = <0 0xe6160000 0 0x0100>;
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,r8a7793-sysc";
reg = <0 0xe6180000 0 0x0200>;
diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index 8d1b35afaf82..569e3f0e97a5 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -18,6 +18,8 @@
aliases {
serial0 = &scif2;
+ i2c10 = &gpioi2c4;
+ i2c12 = &i2cexio4;
};
chosen {
@@ -135,6 +137,29 @@
#clock-cells = <0>;
clock-frequency = <148500000>;
};
+
+ gpioi2c4: i2c-10 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "i2c-gpio";
+ status = "disabled";
+ gpios = <&gpio4 9 GPIO_ACTIVE_HIGH /* sda */
+ &gpio4 8 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,delay-us = <5>;
+ };
+
+ /*
+ * I2C4 is routed to EXIO connector B, pins 73 (SCL) + 74 (SDA).
+ * A fallback to GPIO is provided.
+ */
+ i2cexio4: i2c-14 {
+ compatible = "i2c-demux-pinctrl";
+ i2c-parent = <&i2c4>, <&gpioi2c4>;
+ i2c-bus-name = "i2c-exio4";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
&du {
@@ -165,8 +190,8 @@
pinctrl-names = "default";
du_pins: du {
- groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0";
- function = "du";
+ groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_clk0_out";
+ function = "du1";
};
scif2_pins: scif2 {
@@ -194,6 +219,11 @@
function = "i2c1";
};
+ i2c4_pins: i2c4 {
+ groups = "i2c4";
+ function = "i2c4";
+ };
+
vin0_pins: vin0 {
groups = "vin0_data8", "vin0_clk";
function = "vin0";
@@ -207,11 +237,25 @@
sdhi0_pins: sd0 {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
};
sdhi1_pins: sd1 {
groups = "sdhi1_data4", "sdhi1_ctrl";
function = "sdhi1";
+ power-source = <3300>;
+ };
+
+ sdhi1_pins_uhs: sd1_uhs {
+ groups = "sdhi1_data4", "sdhi1_ctrl";
+ function = "sdhi1";
+ power-source = <1800>;
};
};
@@ -255,23 +299,28 @@
&sdhi0 {
pinctrl-0 = <&sdhi0_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi0>;
vqmmc-supply = <&vccq_sdhi0>;
cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
status = "okay";
};
&sdhi1 {
pinctrl-0 = <&sdhi1_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi1_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi1>;
vqmmc-supply = <&vccq_sdhi1>;
cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;
+ sd-uhs-sdr50;
status = "okay";
};
@@ -296,6 +345,11 @@
};
};
+&i2c4 {
+ pinctrl-0 = <&i2c4_pins>;
+ pinctrl-names = "i2c-exio4";
+};
+
&vin0 {
status = "okay";
pinctrl-0 = <&vin0_pins>;
diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 69e4f4fad89b..fb576dba748c 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -319,7 +319,7 @@
"ch12";
clocks = <&mstp5_clks R8A7794_CLK_AUDIO_DMAC0>;
clock-names = "fck";
- power-domains = <&cpg_clocks>;
+ power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
#dma-cells = <1>;
dma-channels = <13>;
};
@@ -411,7 +411,7 @@
scifb0: serial@e6c20000 {
compatible = "renesas,scifb-r8a7794",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c20000 0 64>;
+ reg = <0 0xe6c20000 0 0x100>;
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>;
clock-names = "fck";
@@ -425,7 +425,7 @@
scifb1: serial@e6c30000 {
compatible = "renesas,scifb-r8a7794",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6c30000 0 64>;
+ reg = <0 0xe6c30000 0 0x100>;
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>;
clock-names = "fck";
@@ -439,7 +439,7 @@
scifb2: serial@e6ce0000 {
compatible = "renesas,scifb-r8a7794",
"renesas,rcar-gen2-scifb", "renesas,scifb";
- reg = <0 0xe6ce0000 0 64>;
+ reg = <0 0xe6ce0000 0 0x100>;
interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>;
clock-names = "fck";
@@ -731,6 +731,7 @@
dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
<&dmac1 0xcd>, <&dmac1 0xce>;
dma-names = "tx", "rx", "tx", "rx";
+ max-frequency = <195000000>;
power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -743,6 +744,7 @@
dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
<&dmac1 0xc1>, <&dmac1 0xc2>;
dma-names = "tx", "rx", "tx", "rx";
+ max-frequency = <97500000>;
power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -755,6 +757,7 @@
dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
<&dmac1 0xd3>, <&dmac1 0xd4>;
dma-names = "tx", "rx", "tx", "rx";
+ max-frequency = <97500000>;
power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -1025,8 +1028,7 @@
clocks = <&extal_clk &usb_extal_clk>;
#clock-cells = <1>;
clock-output-names = "main", "pll0", "pll1", "pll3",
- "lb", "qspi", "sdh", "sd0", "z",
- "rcan";
+ "lb", "qspi", "sdh", "sd0", "rcan";
#power-domain-cells = <0>;
};
/* Variable factor clocks */
@@ -1260,7 +1262,7 @@
mstp7_clks: mstp7_clks@e615014c {
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
- clocks = <&mp_clk>, <&mp_clk>,
+ clocks = <&mp_clk>, <&hp_clk>,
<&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
<&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
<&zx_clk>;
@@ -1380,6 +1382,11 @@
reg = <0 0xe6160000 0 0x0100>;
};
+ prr: chipid@ff000044 {
+ compatible = "renesas,prr";
+ reg = <0 0xff000044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,r8a7794-sysc";
reg = <0 0xe6180000 0 0x0200>;
@@ -1488,67 +1495,67 @@
"mix.0", "mix.1",
"dvc.0", "dvc.1",
"clk_a", "clk_b", "clk_c", "clk_i";
- power-domains = <&cpg_clocks>;
+ power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
status = "disabled";
rcar_sound,dvc {
- dvc0: dvc@0 {
+ dvc0: dvc-0 {
dmas = <&audma0 0xbc>;
dma-names = "tx";
};
- dvc1: dvc@1 {
+ dvc1: dvc-1 {
dmas = <&audma0 0xbe>;
dma-names = "tx";
};
};
rcar_sound,mix {
- mix0: mix@0 { };
- mix1: mix@1 { };
+ mix0: mix-0 { };
+ mix1: mix-1 { };
};
rcar_sound,ctu {
- ctu00: ctu@0 { };
- ctu01: ctu@1 { };
- ctu02: ctu@2 { };
- ctu03: ctu@3 { };
- ctu10: ctu@4 { };
- ctu11: ctu@5 { };
- ctu12: ctu@6 { };
- ctu13: ctu@7 { };
+ ctu00: ctu-0 { };
+ ctu01: ctu-1 { };
+ ctu02: ctu-2 { };
+ ctu03: ctu-3 { };
+ ctu10: ctu-4 { };
+ ctu11: ctu-5 { };
+ ctu12: ctu-6 { };
+ ctu13: ctu-7 { };
};
rcar_sound,src {
- src@0 {
+ src-0 {
status = "disabled";
};
- src1: src@1 {
+ src1: src-1 {
interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x87>, <&audma0 0x9c>;
dma-names = "rx", "tx";
};
- src2: src@2 {
+ src2: src-2 {
interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x89>, <&audma0 0x9e>;
dma-names = "rx", "tx";
};
- src3: src@3 {
+ src3: src-3 {
interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x8b>, <&audma0 0xa0>;
dma-names = "rx", "tx";
};
- src4: src@4 {
+ src4: src-4 {
interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x8d>, <&audma0 0xb0>;
dma-names = "rx", "tx";
};
- src5: src@5 {
+ src5: src-5 {
interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x8f>, <&audma0 0xb2>;
dma-names = "rx", "tx";
};
- src6: src@6 {
+ src6: src-6 {
interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x91>, <&audma0 0xb4>;
dma-names = "rx", "tx";
@@ -1556,61 +1563,61 @@
};
rcar_sound,ssi {
- ssi0: ssi@0 {
+ ssi0: ssi-0 {
interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x01>, <&audma0 0x02>,
<&audma0 0x15>, <&audma0 0x16>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi1: ssi@1 {
+ ssi1: ssi-1 {
interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x03>, <&audma0 0x04>,
<&audma0 0x49>, <&audma0 0x4a>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi2: ssi@2 {
+ ssi2: ssi-2 {
interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x05>, <&audma0 0x06>,
<&audma0 0x63>, <&audma0 0x64>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi3: ssi@3 {
+ ssi3: ssi-3 {
interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x07>, <&audma0 0x08>,
<&audma0 0x6f>, <&audma0 0x70>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi4: ssi@4 {
+ ssi4: ssi-4 {
interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x09>, <&audma0 0x0a>,
<&audma0 0x71>, <&audma0 0x72>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi5: ssi@5 {
+ ssi5: ssi-5 {
interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x0b>, <&audma0 0x0c>,
<&audma0 0x73>, <&audma0 0x74>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi6: ssi@6 {
+ ssi6: ssi-6 {
interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x0d>, <&audma0 0x0e>,
<&audma0 0x75>, <&audma0 0x76>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi7: ssi@7 {
+ ssi7: ssi-7 {
interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x0f>, <&audma0 0x10>,
<&audma0 0x79>, <&audma0 0x7a>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi8: ssi@8 {
+ ssi8: ssi-8 {
interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x11>, <&audma0 0x12>,
<&audma0 0x7b>, <&audma0 0x7c>;
dma-names = "rx", "tx", "rxu", "txu";
};
- ssi9: ssi@9 {
+ ssi9: ssi-9 {
interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x13>, <&audma0 0x14>,
<&audma0 0x7d>, <&audma0 0x7e>;
diff --git a/arch/arm/boot/dts/rk1108-evb.dts b/arch/arm/boot/dts/rk1108-evb.dts
new file mode 100644
index 000000000000..3956cff4ca79
--- /dev/null
+++ b/arch/arm/boot/dts/rk1108-evb.dts
@@ -0,0 +1,69 @@
+/*
+ * 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 "rk1108.dtsi"
+
+/ {
+ model = "Rockchip RK1108 Evaluation board";
+ compatible = "rockchip,rk1108-evb", "rockchip,rk1108";
+
+ memory@60000000 {
+ device_type = "memory";
+ reg = <0x60000000 0x08000000>;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk1108.dtsi b/arch/arm/boot/dts/rk1108.dtsi
new file mode 100644
index 000000000000..d7700235e0f5
--- /dev/null
+++ b/arch/arm/boot/dts/rk1108.dtsi
@@ -0,0 +1,452 @@
+/*
+ * 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/clock/rk1108-cru.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "rockchip,rk1108";
+
+ 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>;
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma: pdma@102a0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x102a0000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMAC>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ bus_intmem@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x2000>;
+ };
+
+ uart2: serial@10210000 {
+ compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart";
+ reg = <0x10210000 0x100>;
+ interrupts = <GIC_SPI 46 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 = <&uart2m0_xfer>;
+ status = "disabled";
+ };
+
+ uart1: serial@10220000 {
+ compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart";
+ reg = <0x10220000 0x100>;
+ interrupts = <GIC_SPI 45 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";
+ };
+
+ uart0: serial@10230000 {
+ compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart";
+ reg = <0x10230000 0x100>;
+ interrupts = <GIC_SPI 44 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";
+ };
+
+ grf: syscon@10300000 {
+ compatible = "rockchip,rk1108-grf", "syscon";
+ reg = <0x10300000 0x1000>;
+ };
+
+ pmugrf: syscon@20060000 {
+ compatible = "rockchip,rk1108-pmugrf", "syscon";
+ reg = <0x20060000 0x1000>;
+ };
+
+ cru: clock-controller@20200000 {
+ compatible = "rockchip,rk1108-cru";
+ reg = <0x20200000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ emmc: dwmmc@30110000 {
+ compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x30110000 0x4000>;
+ status = "disabled";
+ };
+
+ sdio: dwmmc@30120000 {
+ compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x30120000 0x4000>;
+ status = "disabled";
+ };
+
+ sdmmc: dwmmc@30130000 {
+ compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 100000000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x30130000 0x4000>;
+ 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(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk1108-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmugrf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@20030000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20030000 0x100>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@10310000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x10310000 0x100>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@10320000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x10320000 0x100>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@10330000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x10330000 0x100>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>;
+
+ 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;
+ };
+
+ pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_none_drv_12ma: pcfg-pull-none-drv-12ma {
+ drive-strength = <12>;
+ };
+
+ pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_none_drv_4ma: pcfg-pull-none-drv-4ma {
+ drive-strength = <4>;
+ };
+
+ pcfg_pull_up_drv_4ma: pcfg-pull-up-drv-4ma {
+ bias-pull-up;
+ drive-strength = <4>;
+ };
+
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ pcfg_input_high: pcfg-input-high {
+ bias-pull-up;
+ input-enable;
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>,
+ <2 RK_PD4 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ i2c2m1 {
+ i2c2m1_xfer: i2c2m1-xfer {
+ rockchip,pins = <0 RK_PC2 RK_FUNC_2 &pcfg_pull_none>,
+ <0 RK_PC6 RK_FUNC_3 &pcfg_pull_none>;
+ };
+
+ i2c2m1_gpio: i2c2m1-gpio {
+ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>,
+ <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ i2c2m05v {
+ i2c2m05v_xfer: i2c2m05v-xfer {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_2 &pcfg_pull_none>,
+ <1 RK_PD4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ i2c2m05v_gpio: i2c2m05v-gpio {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>,
+ <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <0 RK_PB6 RK_FUNC_1 &pcfg_pull_none>,
+ <0 RK_PC4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <3 RK_PC5 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+ };
+
+ sdmmc_cd: sdmmc-cd {
+ rockchip,pins = <0 RK_PA1 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+ };
+
+ sdmmc_bus1: sdmmc-bus1 {
+ rockchip,pins = <3 RK_PC3 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+ };
+
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <3 RK_PC3 RK_FUNC_1 &pcfg_pull_up_drv_4ma>,
+ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_up_drv_4ma>,
+ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_up_drv_4ma>,
+ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_up_drv_4ma>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <3 RK_PA6 RK_FUNC_1 &pcfg_pull_up>,
+ <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts_gpio: uart0-rts-gpio {
+ rockchip,pins = <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up>,
+ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <1 RK_PD0 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <1 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2m0 {
+ uart2m0_xfer: uart2m0-xfer {
+ rockchip,pins = <2 RK_PD2 RK_FUNC_1 &pcfg_pull_up>,
+ <2 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2m1 {
+ uart2m1_xfer: uart2m1-xfer {
+ rockchip,pins = <3 RK_PC3 RK_FUNC_2 &pcfg_pull_up>,
+ <3 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2_5v {
+ uart2_5v_cts: uart2_5v-cts {
+ rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart2_5v_rts: uart2_5v-rts {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
index 8db9e9b197a2..2f5f15524fba 100644
--- a/arch/arm/boot/dts/rk3036-evb.dts
+++ b/arch/arm/boot/dts/rk3036-evb.dts
@@ -46,7 +46,7 @@
model = "Rockchip RK3036 Evaluation board";
compatible = "rockchip,rk3036-evb", "rockchip,rk3036";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts
index 1df1557a46c3..3de958ec29c0 100644
--- a/arch/arm/boot/dts/rk3036-kylin.dts
+++ b/arch/arm/boot/dts/rk3036-kylin.dts
@@ -46,7 +46,7 @@
model = "Rockchip RK3036 KylinBoard";
compatible = "rockchip,rk3036-kylin", "rockchip,rk3036";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x20000000>;
};
diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
index 7c2dc19925a1..4ed49a243e5c 100644
--- a/arch/arm/boot/dts/rk3036.dtsi
+++ b/arch/arm/boot/dts/rk3036.dtsi
@@ -44,9 +44,11 @@
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/clock/rk3036-cru.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
compatible = "rockchip,rk3036";
interrupt-parent = <&gic>;
@@ -243,7 +245,7 @@
compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x10214000 0x4000>;
clock-frequency = <37500000>;
- clock-freq-min-max = <400000 37500000>;
+ max-frequency = <37500000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
clock-names = "biu", "ciu";
fifo-depth = <0x100>;
@@ -254,7 +256,7 @@
sdio: dwmmc@10218000 {
compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x10218000 0x4000>;
- clock-freq-min-max = <400000 37500000>;
+ max-frequency = <37500000>;
clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
<&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
@@ -270,7 +272,7 @@
bus-width = <8>;
cap-mmc-highspeed;
clock-frequency = <37500000>;
- clock-freq-min-max = <400000 37500000>;
+ max-frequency = <37500000>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
<&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
index bc674ee206ec..c0d8b5446ba7 100644
--- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts
+++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
@@ -49,7 +49,7 @@
model = "bq Curie 2";
compatible = "mundoreader,bq-curie2", "rockchip,rk3066a";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts
index a2b763e949b4..0a54c4beff8d 100644
--- a/arch/arm/boot/dts/rk3066a-marsboard.dts
+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts
@@ -47,7 +47,7 @@
model = "MarsBoard RK3066";
compatible = "haoyu,marsboard-rk3066", "rockchip,rk3066a";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
new file mode 100644
index 000000000000..658eb7ddeaf5
--- /dev/null
+++ b/arch/arm/boot/dts/rk3066a-mk808.dts
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2016 Paweł Jarosz <paweljarosz3691@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 "rk3066a.dtsi"
+
+/ {
+ model = "Rikomagic MK808";
+ compatible = "rikomagic,mk808", "rockchip,rk3066a";
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory@60000000 {
+ reg = <0x60000000 0x40000000>;
+ device_type = "memory";
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue {
+ label = "mk808:blue:power";
+ gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ vcc_io: vcc-io {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&host_drv>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-name = "host-pwr";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_otg: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&otg_drv>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-name = "vcc_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&sdmmc_pwr>;
+ pinctrl-names = "default";
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_wifi: sdio-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&wifi_pwr>;
+ pinctrl-names = "default";
+ regulator-name = "vcc_wifi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+};
+
+&mmc0 {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ num-slots = <1>;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&mmc1 {
+ bus-width = <4>;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>;
+ pinctrl-names = "default";
+ vmmc-supply = <&vcc_wifi>;
+ status = "okay";
+};
+
+&pinctrl {
+ usb-host {
+ host_drv: host-drv {
+ rockchip,pins = <RK_GPIO0 6 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ usb-otg {
+ otg_drv: otg-drv {
+ rockchip,pins = <RK_GPIO0 5 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <RK_GPIO3 7 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ sdio {
+ wifi_pwr: wifi-pwr {
+ rockchip,pins = <RK_GPIO3 24 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts
index 6e7f2187a0e3..82465b644443 100644
--- a/arch/arm/boot/dts/rk3066a-rayeager.dts
+++ b/arch/arm/boot/dts/rk3066a-rayeager.dts
@@ -48,7 +48,7 @@
model = "Rayeager PX2";
compatible = "chipspark,rayeager-px2", "rockchip,rk3066a";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index 0d0dae3a1694..e498c362b9e7 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -151,6 +151,14 @@
#clock-cells = <1>;
#reset-cells = <1>;
+ assigned-clocks = <&cru PLL_CPLL>, <&cru PLL_GPLL>,
+ <&cru ACLK_CPU>, <&cru HCLK_CPU>,
+ <&cru PCLK_CPU>, <&cru ACLK_PERI>,
+ <&cru HCLK_PERI>, <&cru PCLK_PERI>;
+ assigned-clock-rates = <400000000>, <594000000>,
+ <300000000>, <150000000>,
+ <75000000>, <300000000>,
+ <150000000>, <75000000>;
};
timer@2000e000 {
@@ -162,7 +170,7 @@
};
efuse: efuse@20010000 {
- compatible = "rockchip,rockchip-efuse";
+ compatible = "rockchip,rk3066a-efuse";
reg = <0x20010000 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
@@ -197,7 +205,7 @@
clock-names = "saradc", "apb_pclk";
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
#io-channel-cells = <1>;
- resets = <&cru SRST_SARADC>;
+ resets = <&cru SRST_TSADC>;
reset-names = "saradc-apb";
status = "disabled";
};
@@ -628,15 +636,26 @@
};
&mmc0 {
+ clock-frequency = <50000000>;
+ dmas = <&dmac2 1>;
+ dma-names = "rx-tx";
+ max-frequency = <50000000>;
pinctrl-names = "default";
pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>;
};
&mmc1 {
+ dmas = <&dmac2 3>;
+ dma-names = "rx-tx";
pinctrl-names = "default";
pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus4>;
};
+&emmc {
+ dmas = <&dmac2 4>;
+ dma-names = "rx-tx";
+};
+
&pwm0 {
pinctrl-names = "default";
pinctrl-0 = <&pwm0_out>;
@@ -668,21 +687,29 @@
};
&uart0 {
+ dmas = <&dmac1_s 0>, <&dmac1_s 1>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart0_xfer>;
};
&uart1 {
+ dmas = <&dmac1_s 2>, <&dmac1_s 3>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart1_xfer>;
};
&uart2 {
+ dmas = <&dmac2 6>, <&dmac2 7>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart2_xfer>;
};
&uart3 {
+ dmas = <&dmac2 8>, <&dmac2 9>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart3_xfer>;
};
diff --git a/arch/arm/boot/dts/rk3188-px3-evb.dts b/arch/arm/boot/dts/rk3188-px3-evb.dts
new file mode 100644
index 000000000000..df727bafd6dc
--- /dev/null
+++ b/arch/arm/boot/dts/rk3188-px3-evb.dts
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2016 Andy Yan <andy.yan@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 <dt-bindings/input/input.h>
+#include "rk3188.dtsi"
+
+/ {
+ model = "Rockchip PX3-EVB";
+ compatible = "rockchip,px3-evb", "rockchip,px3", "rockchip,rk3188";
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory@60000000 {
+ reg = <0x60000000 0x80000000>;
+ device_type = "memory";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ power {
+ gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "GPIO Key Power";
+ linux,input-type = <1>;
+ wakeup-source;
+ debounce-interval = <100>;
+ };
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ accelerometer@18 {
+ compatible = "bosch,bma250";
+ reg = <0x18>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ rk808: pmic@1c {
+ compatible = "rockchip,rk818";
+ reg = <0x1c>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ 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_io>;
+ vcc9-supply = <&vcc_io>;
+
+ 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>;
+ };
+ };
+
+ vcc_cif: LDO_REG1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_cif";
+ };
+
+ vcc_jetta33: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_jetta33";
+ };
+
+ 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>;
+ };
+ };
+
+ lvds_12: LDO_REG4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "lvds_12";
+ };
+
+ lvds_25: LDO_REG5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "lvds_25";
+ };
+
+ cif_18: LDO_REG6 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "cif_18";
+ };
+
+ vcc_sd: LDO_REG7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_sd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ wl_18: LDO_REG8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "wl_18";
+ };
+
+ lcd_33: SWITCH_REG1 {
+ regulator-name = "lcd_33";
+ };
+ };
+ };
+
+};
+
+&i2c2 {
+ gsl1680: touchscreen@40 {
+ compatible = "silead,gsl1680";
+ reg = <0x40>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+ power-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <1280>;
+ silead,max-fingers = <5>;
+ };
+};
+
+&mmc0 {
+ num-slots = <1>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd>;
+
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+};
+
+&pinctrl {
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <2 31 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
index 1da46d138029..5e8a235ed02d 100644
--- a/arch/arm/boot/dts/rk3188-radxarock.dts
+++ b/arch/arm/boot/dts/rk3188-radxarock.dts
@@ -48,7 +48,7 @@
model = "Radxa Rock";
compatible = "radxa,rock", "rockchip,rk3188";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 31f81b265cef..869e189331ec 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -147,7 +147,7 @@
};
efuse: efuse@20010000 {
- compatible = "rockchip,rockchip-efuse";
+ compatible = "rockchip,rk3188-efuse";
reg = <0x20010000 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 904668e2e666..58834330a5ba 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -46,7 +46,7 @@
model = "Rockchip RK3228 Evaluation board";
compatible = "rockchip,rk3228-evb", "rockchip,rk3228";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts
index b6a12035a6bb..dcdd0cee619e 100644
--- a/arch/arm/boot/dts/rk3229-evb.dts
+++ b/arch/arm/boot/dts/rk3229-evb.dts
@@ -46,7 +46,7 @@
model = "Rockchip RK3229 Evaluation board";
compatible = "rockchip,rk3229-evb", "rockchip,rk3229";
- memory {
+ memory@60000000 {
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 9e6bf0e311bb..9d3aee5abc15 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -44,9 +44,11 @@
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/clock/rk3228-cru.h>
#include <dt-bindings/thermal/thermal.h>
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
interrupt-parent = <&gic>;
aliases {
@@ -402,7 +404,7 @@
reg = <0x30020000 0x4000>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <37500000>;
- clock-freq-min-max = <400000 37500000>;
+ max-frequency = <37500000>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
<&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
index d59208b5eb6c..bf7ccfad3260 100644
--- a/arch/arm/boot/dts/rk3288-evb.dtsi
+++ b/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -43,7 +43,7 @@
#include "rk3288.dtsi"
/ {
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3288-fennec.dts b/arch/arm/boot/dts/rk3288-fennec.dts
index 2e3c34135ed8..805c0d26770b 100644
--- a/arch/arm/boot/dts/rk3288-fennec.dts
+++ b/arch/arm/boot/dts/rk3288-fennec.dts
@@ -46,7 +46,7 @@
model = "Rockchip RK3288 Fennec Board";
compatible = "rockchip,rk3288-fennec", "rockchip,rk3288";
- memory {
+ memory@0 {
reg = <0x0 0x80000000>;
device_type = "memory";
};
diff --git a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi
index ec418c99de95..d242588bae0d 100644
--- a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi
+++ b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi
@@ -45,7 +45,7 @@
#include "rk3288.dtsi"
/ {
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
index 114c90fb65e2..44935af1fb0e 100644
--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
+++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
@@ -44,7 +44,7 @@
#include "rk3288.dtsi"
/ {
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts
index 24488421f0f0..441d450fd151 100644
--- a/arch/arm/boot/dts/rk3288-miqi.dts
+++ b/arch/arm/boot/dts/rk3288-miqi.dts
@@ -52,7 +52,7 @@
stdout-path = "serial2:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts
index 56dd377d5658..bc6d10054f6a 100644
--- a/arch/arm/boot/dts/rk3288-popmetal.dts
+++ b/arch/arm/boot/dts/rk3288-popmetal.dts
@@ -48,7 +48,7 @@
model = "PopMetal-RK3288";
compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288";
- memory{
+ memory@0 {
device_type = "memory";
reg = <0 0x80000000>;
};
@@ -68,7 +68,7 @@
pinctrl-0 = <&pwrbtn>;
power {
- gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "GPIO Key Power";
linux,input-type = <1>;
@@ -79,7 +79,7 @@
ir: ir-receiver {
compatible = "gpio-ir-receiver";
- gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&ir_int>;
};
@@ -94,7 +94,7 @@
vcc_sd: sdmmc-regulator {
compatible = "regulator-fixed";
- gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
+ gpio = <&gpio7 RK_PB3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_pwr>;
regulator-name = "vcc_sd";
@@ -128,7 +128,7 @@
vcc28_dvp: vcc28-dvp-regulator {
compatible = "regulator-fixed";
enable-active-high;
- gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&dvp_pwr>;
regulator-name = "vcc28_dvp";
@@ -147,6 +147,8 @@
bus-width = <8>;
cap-mmc-highspeed;
disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
non-removable;
num-slots = <1>;
pinctrl-names = "default";
@@ -165,6 +167,10 @@
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
vmmc-supply = <&vcc_sd>;
vqmmc-supply = <&vccio_sd>;
status = "okay";
@@ -174,7 +180,7 @@
phy-supply = <&vcc_lan>;
phy-mode = "rgmii";
clock_in_out = "input";
- snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-gpio = <&gpio4 RK_PB0 0>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 1000000>;
assigned-clocks = <&cru SCLK_MAC>;
@@ -280,7 +286,7 @@
vccio_sd: LDO_REG2 {
regulator-always-on;
regulator-boot-on;
- regulator-min-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_sd";
regulator-state-mem {
@@ -443,43 +449,43 @@
&pinctrl {
ak8963 {
comp_int: comp-int {
- rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>;
+ rockchip,pins = <8 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
buttons {
pwrbtn: pwrbtn {
- rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
dvp {
dvp_pwr: dvp-pwr {
- rockchip,pins = <0 17 RK_FUNC_GPIO &pcfg_pull_none>;
+ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
ir {
ir_int: ir-int {
- rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_up>;
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
mma8452 {
gsensor_int: gsensor-int {
- rockchip,pins = <8 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ rockchip,pins = <8 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
pmic {
pmic_int: pmic-int {
- rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
sdmmc {
sdmmc_pwr: sdmmc-pwr {
- rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ rockchip,pins = <7 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts
index 4b8a8adb243c..04faa72dbd95 100644
--- a/arch/arm/boot/dts/rk3288-r89.dts
+++ b/arch/arm/boot/dts/rk3288-r89.dts
@@ -48,7 +48,7 @@
/ {
compatible = "netxeon,r89", "rockchip,rk3288";
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
index bb1f01e037ba..b25ba806d5ee 100644
--- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi
+++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
@@ -42,7 +42,7 @@
#include "rk3288.dtsi"
/ {
- memory {
+ memory@0 {
reg = <0x0 0x80000000>;
device_type = "memory";
};
diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi
index 3dd2cca48c11..2251d28e9d2a 100644
--- a/arch/arm/boot/dts/rk3288-veyron.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
@@ -47,7 +47,7 @@
#include "rk3288.dtsi"
/ {
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x80000000>;
};
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 74a749c566ee..4fad13368a7b 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -46,9 +46,11 @@
#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/power/rk3288-power.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
compatible = "rockchip,rk3288";
interrupt-parent = <&gic>;
@@ -227,7 +229,7 @@
sdmmc: dwmmc@ff0c0000 {
compatible = "rockchip,rk3288-dw-mshc";
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -239,7 +241,7 @@
sdio0: dwmmc@ff0d0000 {
compatible = "rockchip,rk3288-dw-mshc";
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
<&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -251,7 +253,7 @@
sdio1: dwmmc@ff0e0000 {
compatible = "rockchip,rk3288-dw-mshc";
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>,
<&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -263,7 +265,7 @@
emmc: dwmmc@ff0f0000 {
compatible = "rockchip,rk3288-dw-mshc";
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
<&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -1115,7 +1117,7 @@
};
efuse: efuse@ffb40000 {
- compatible = "rockchip,rockchip-efuse";
+ compatible = "rockchip,rk3288-efuse";
reg = <0xffb40000 0x20>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 8fbd3c806fa0..0b45811cf28b 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -44,9 +44,11 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>
-#include "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
interrupt-parent = <&gic>;
aliases {
diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 7173ec9059a1..ceb9783ff7e1 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -735,6 +735,11 @@
atmel,clk-output-range = <0 83000000>;
};
+ securam_clk: securam_clk {
+ #clock-cells = <0>;
+ reg = <51>;
+ };
+
i2s0_clk: i2s0_clk {
#clock-cells = <0>;
reg = <54>;
@@ -1030,6 +1035,7 @@
#address-cells = <1>;
#size-cells = <0>;
clocks = <&twi0_clk>;
+ atmel,fifo-size = <16>;
status = "disabled";
};
@@ -1058,6 +1064,15 @@
status = "disabled";
};
+ securam: sram@f8044000 {
+ compatible = "atmel,sama5d2-securam", "mmio-sram";
+ reg = <0xf8044000 0x1420>;
+ clocks = <&securam_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xf8044000 0x1420>;
+ };
+
rstc@f8048000 {
compatible = "atmel,sama5d3-rstc";
reg = <0xf8048000 0x10>;
@@ -1088,30 +1103,12 @@
status = "disabled";
};
- sckc@f8048050 {
- compatible = "atmel,at91sam9x5-sckc";
+ clk32k: sckc@f8048050 {
+ compatible = "atmel,sama5d4-sckc";
reg = <0xf8048050 0x4>;
- slow_rc_osc: slow_rc_osc {
- compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
- #clock-cells = <0>;
- clock-frequency = <32768>;
- clock-accuracy = <250000000>;
- atmel,startup-time-usec = <75>;
- };
-
- slow_osc: slow_osc {
- compatible = "atmel,at91sam9x5-clk-slow-osc";
- #clock-cells = <0>;
- clocks = <&slow_xtal>;
- atmel,startup-time-usec = <1200000>;
- };
-
- clk32k: slowck {
- compatible = "atmel,at91sam9x5-clk-slow";
- #clock-cells = <0>;
- clocks = <&slow_rc_osc &slow_osc>;
- };
+ clocks = <&slow_xtal>;
+ #clock-cells = <0>;
};
rtc@f80480b0 {
@@ -1231,6 +1228,7 @@
#address-cells = <1>;
#size-cells = <0>;
clocks = <&twi1_clk>;
+ atmel,fifo-size = <16>;
status = "disabled";
};
@@ -1260,6 +1258,11 @@
clocks = <&pioA_clk>;
};
+ secumod@fc040000 {
+ compatible = "atmel,sama5d2-secumod", "syscon";
+ reg = <0xfc040000 0x100>;
+ };
+
tdes@fc044000 {
compatible = "atmel,at91sam9g46-tdes";
reg = <0xfc044000 0x100>;
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 4c84d333fc7e..b06448ba6649 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -549,8 +549,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB30 periph A */
- AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PB31 periph A with pullup */
+ <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+ AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
};
};
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 65e725fb5679..4f60c1b7b137 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -1314,30 +1314,11 @@
status = "disabled";
};
- sckc@fc068650 {
- compatible = "atmel,at91sam9x5-sckc";
+ clk32k: sckc@fc068650 {
+ compatible = "atmel,sama5d4-sckc";
reg = <0xfc068650 0x4>;
-
- slow_rc_osc: slow_rc_osc {
- compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
- #clock-cells = <0>;
- clock-frequency = <32768>;
- clock-accuracy = <250000000>;
- atmel,startup-time-usec = <75>;
- };
-
- slow_osc: slow_osc {
- compatible = "atmel,at91sam9x5-clk-slow-osc";
- #clock-cells = <0>;
- clocks = <&slow_xtal>;
- atmel,startup-time-usec = <1200000>;
- };
-
- clk32k: slowck {
- compatible = "atmel,at91sam9x5-clk-slow";
- #clock-cells = <0>;
- clocks = <&slow_rc_osc &slow_osc>;
- };
+ #clock-cells = <0>;
+ clocks = <&slow_xtal>;
};
rtc@fc0686b0 {
@@ -1461,8 +1442,8 @@
dbgu {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
- <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE>, /* conflicts with D14 and TDI */
- <AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* conflicts with D15 and TDO */
+ <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* conflicts with D14 and TDI */
+ AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* conflicts with D15 and TDO */
};
};
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 032fe2f14b16..e1267590b575 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -8,8 +8,6 @@
* kind, whether express or implied.
*/
-/include/ "skeleton.dtsi"
-
#include <dt-bindings/clock/sh73a0-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
@@ -17,6 +15,8 @@
/ {
compatible = "renesas,sh73a0";
interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
cpus {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 9f48141270b8..da689659131f 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -686,6 +686,12 @@
arm,data-latency = <2 1 1>;
prefetch-data = <1>;
prefetch-instr = <1>;
+ arm,shared-override;
+ arm,double-linefill = <1>;
+ arm,double-linefill-incr = <0>;
+ arm,double-linefill-wrap = <1>;
+ arm,prefetch-drop = <0>;
+ arm,prefetch-offset = <7>;
};
mmc: dwmmc0@ff704000 {
@@ -700,11 +706,38 @@
status = "disabled";
};
+ nand0: nand@ff900000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "denali,denali-nand-dt";
+ reg = <0xff900000 0x100000>,
+ <0xffb80000 0x10000>;
+ reg-names = "nand_data", "denali_reg";
+ interrupts = <0x0 0x90 0x4>;
+ dma-mask = <0xffffffff>;
+ clocks = <&nand_clk>;
+ status = "disabled";
+ };
+
ocram: sram@ffff0000 {
compatible = "mmio-sram";
reg = <0xffff0000 0x10000>;
};
+ qspi: spi@ff705000 {
+ compatible = "cdns,qspi-nor";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xff705000 0x1000>,
+ <0xffa00000 0x1000>;
+ interrupts = <0 151 4>;
+ cdns,fifo-depth = <128>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x00000000>;
+ clocks = <&qspi_clk>;
+ status = "disabled";
+ };
+
rst: rstmgr@ffd05000 {
#reset-cells = <1>;
compatible = "altr,rst-mgr";
diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
index f520cbff5e1c..551c636a4f01 100644
--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
@@ -562,6 +562,21 @@
status = "disabled";
};
+ spi1: spi@ffda5000 {
+ compatible = "snps,dw-apb-ssi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xffda5000 0x100>;
+ interrupts = <0 102 4>;
+ num-chipselect = <4>;
+ bus-num = <0>;
+ /*32bit_access;*/
+ tx-dma-channel = <&pdma 16>;
+ rx-dma-channel = <&pdma 17>;
+ clocks = <&spi_m_clk>;
+ status = "disabled";
+ };
+
sdr: sdr@ffc25000 {
compatible = "syscon";
reg = <0xffcfb100 0x80>;
@@ -573,6 +588,9 @@
interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
cache-unified;
cache-level = <2>;
+ prefetch-data = <1>;
+ prefetch-instr = <1>;
+ arm,shared-override;
};
mmc: dwmmc0@ff808000 {
@@ -657,6 +675,20 @@
};
};
+ qspi: spi@ff809000 {
+ compatible = "cdns,qspi-nor";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xff809000 0x100>,
+ <0xffa00000 0x100000>;
+ interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+ cdns,fifo-depth = <128>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x00000000>;
+ clocks = <&qspi_clk>;
+ status = "disabled";
+ };
+
rst: rstmgr@ffd05000 {
#reset-cells = <1>;
compatible = "altr,rst-mgr";
diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
index 8e3a4adc389f..eb00ae37f316 100644
--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
@@ -36,6 +36,30 @@
reg = <0x0 0x40000000>; /* 1GB */
};
+ a10leds {
+ compatible = "gpio-leds";
+
+ a10sr_led0 {
+ label = "a10sr-led0";
+ gpios = <&a10sr_gpio 0 1>;
+ };
+
+ a10sr_led1 {
+ label = "a10sr-led1";
+ gpios = <&a10sr_gpio 1 1>;
+ };
+
+ a10sr_led2 {
+ label = "a10sr-led2";
+ gpios = <&a10sr_gpio 2 1>;
+ };
+
+ a10sr_led3 {
+ label = "a10sr-led3";
+ gpios = <&a10sr_gpio 3 1>;
+ };
+ };
+
soc {
clkmgr@ffd04000 {
clocks {
@@ -75,6 +99,31 @@
status = "okay";
};
+&gpio1 {
+ status = "okay";
+};
+
+&spi1 {
+ status = "okay";
+
+ resource-manager@0 {
+ compatible = "altr,a10sr";
+ reg = <0>;
+ spi-max-frequency = <100000>;
+ /* low-level active IRQ at GPIO1_5 */
+ interrupt-parent = <&portb>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ a10sr_gpio: gpio-controller {
+ compatible = "altr,a10sr-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+};
+
&i2c1 {
speed-mode = <0>;
status = "okay";
diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts b/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts
new file mode 100644
index 000000000000..beb2fc6b9eb6
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 Intel. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+#include "socfpga_arria10_socdk.dtsi"
+
+&qspi {
+ status = "okay";
+
+ flash0: n25q00@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00aa";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+
+ partition@qspi-boot {
+ label = "Boot and fpga data";
+ reg = <0x0 0x2720000>;
+ };
+
+ partition@qspi-rootfs {
+ label = "Root Filesystem - JFFS2";
+ reg = <0x2720000 0x58E0000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
index 3c8867862b0d..f739ead074a2 100644
--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
@@ -82,6 +82,39 @@
status = "okay";
};
+&qspi {
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q256a";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+
+ partition@qspi-boot {
+ /* 8MB for raw data. */
+ label = "Flash 0 Raw Data";
+ reg = <0x0 0x800000>;
+ };
+
+ partition@qspi-rootfs {
+ /* 120MB for jffs2 data. */
+ label = "Flash 0 jffs2 Filesystem";
+ reg = <0x800000 0x7800000>;
+ };
+ };
+};
+
&usb1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
index afea3645ada4..5ecd2ef405e3 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
@@ -18,7 +18,7 @@
/ {
model = "Terasic DE-0(Atlas)";
- compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ compatible = "terasic,de0-atlas", "altr,socfpga-cyclone5", "altr,socfpga";
chosen {
bootargs = "earlyprintk";
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
index f86f9c060d7a..6ad3b1eb9b86 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
+++ b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
@@ -18,7 +18,7 @@
#include "socfpga_cyclone5.dtsi"
/ {
- model = "DENX MCV";
+ model = "Aries/DENX MCV";
compatible = "altr,socfpga-cyclone5", "altr,socfpga";
memory {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
index 7186a29b8b86..e5a98e5696ca 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
@@ -18,8 +18,8 @@
#include "socfpga_cyclone5_mcv.dtsi"
/ {
- model = "DENX MCV EVK";
- compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ model = "Aries/DENX MCV EVK";
+ compatible = "denx,mcvevk", "altr,socfpga-cyclone5", "altr,socfpga";
aliases {
ethernet0 = &gmac0;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
index 15e43f43f244..6306d008f01b 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
@@ -19,7 +19,7 @@
/ {
model = "Altera SOCFPGA Cyclone V SoC Development Kit";
- compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ compatible = "altr,socfpga-cyclone5-socdk", "altr,socfpga-cyclone5", "altr,socfpga";
chosen {
bootargs = "earlyprintk";
@@ -87,6 +87,39 @@
status = "okay";
};
+&qspi {
+ status = "okay";
+
+ flash0: n25q00@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00";
+ reg = <0>; /* chip select */
+ spi-max-frequency = <100000000>;
+
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+
+ partition@qspi-boot {
+ /* 8MB for raw data. */
+ label = "Flash 0 Raw Data";
+ reg = <0x0 0x800000>;
+ };
+
+ partition@qspi-rootfs {
+ /* 120MB for jffs2 data. */
+ label = "Flash 0 jffs2 Filesystem";
+ reg = <0x800000 0x7800000>;
+ };
+ };
+};
+
&usb1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
index 02e22f554ef0..a0c90b3bdfd1 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
@@ -19,7 +19,7 @@
/ {
model = "Terasic SoCkit";
- compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ compatible = "terasic,socfpga-cyclone5-sockit", "altr,socfpga-cyclone5", "altr,socfpga";
chosen {
bootargs = "earlyprintk";
@@ -175,6 +175,27 @@
status = "okay";
};
+&qspi {
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ };
+};
+
&usb1 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
index d79853775061..c3d52f27b21e 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
@@ -80,3 +80,22 @@
&mmc {
status = "okay";
};
+
+&qspi {
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q256a";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+ m25p,fast-read;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
new file mode 100644
index 000000000000..5b7e3c27e6e9
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Altera SOCFPGA Cyclone V SoC Macnica Sodia board";
+ compatible = "macnica,sodia", "altr,socfpga-cyclone5", "altr,socfpga";
+
+ chosen {
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ aliases {
+ ethernet0 = &gmac1;
+ };
+
+ regulator_3_3v: 3-3-v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ leds: gpio-leds {
+ compatible = "gpio-leds";
+
+ hps_led0 {
+ label = "hps:green:led0";
+ gpios = <&portb 12 GPIO_ACTIVE_LOW>;
+ };
+
+ hps_led1 {
+ label = "hps:green:led1";
+ gpios = <&portb 13 GPIO_ACTIVE_LOW>;
+ };
+
+ hps_led2 {
+ label = "hps:green:led2";
+ gpios = <&portb 14 GPIO_ACTIVE_LOW>;
+ };
+
+ hps_led3 {
+ label = "hps:green:led3";
+ gpios = <&portb 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&gmac1 {
+ status = "okay";
+ phy-mode = "rgmii";
+ phy = <&phy0>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ rxdv-skew-ps = <0>;
+ rxc-skew-ps = <3000>;
+ txen-skew-ps = <0>;
+ txc-skew-ps = <3000>;
+ };
+ };
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ eeprom@51 {
+ compatible = "atmel,24c32";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+};
+
+&mmc0 {
+ cd-gpios = <&portb 18 0>;
+ vmmc-supply = <&regulator_3_3v>;
+ vqmmc-supply = <&regulator_3_3v>;
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
index b844473601d2..363ee62457fe 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
@@ -51,7 +51,7 @@
/ {
model = "samtec VIN|ING FPGA";
- compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ compatible = "samtec,vining", "altr,socfpga-cyclone5", "altr,socfpga";
chosen {
bootargs = "console=ttyS0,115200";
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index 449acf0d8272..17ea0abcdbd7 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -118,6 +118,7 @@
block_size = <0xfff>;
dma-masters = <2>;
data-width = <8 8>;
+ multi-block = <1 1 1 1 1 1 1 1>;
};
dma@eb000000 {
@@ -134,6 +135,7 @@
chan_priority = <1>;
block_size = <0xfff>;
data-width = <8 8>;
+ multi-block = <1 1 1 1 1 1 1 1>;
};
fsmc: flash@b0000000 {
diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
index 13029c03d7c6..34c119a66f14 100644
--- a/arch/arm/boot/dts/stih407-clock.dtsi
+++ b/arch/arm/boot/dts/stih407-clock.dtsi
@@ -101,6 +101,7 @@
clocks = <&clk_sysin>;
clock-output-names = "clk-s-a0-pll-ofd-0";
+ clock-critical = <0>; /* clk-s-a0-pll-ofd-0 */
};
clk_s_a0_flexgen: clk-s-a0-flexgen {
@@ -112,6 +113,7 @@
<&clk_sysin>;
clock-output-names = "clk-ic-lmi0";
+ clock-critical = <CLK_IC_LMI0>;
};
};
@@ -126,6 +128,7 @@
"clk-s-c0-fs0-ch1",
"clk-s-c0-fs0-ch2",
"clk-s-c0-fs0-ch3";
+ clock-critical = <0>; /* clk-s-c0-fs0-ch0 */
};
clk_s_c0: clockgen-c@09103000 {
@@ -139,6 +142,7 @@
clocks = <&clk_sysin>;
clock-output-names = "clk-s-c0-pll0-odf-0";
+ clock-critical = <0>; /* clk-s-c0-pll0-odf-0 */
};
clk_s_c0_pll1: clk-s-c0-pll1 {
@@ -194,6 +198,12 @@
"clk-main-disp",
"clk-aux-disp",
"clk-compo-dvp";
+ clock-critical = <CLK_PROC_STFE>,
+ <CLK_ICN_CPU>,
+ <CLK_TX_ICN_DMU>,
+ <CLK_EXT2F_A9>,
+ <CLK_ICN_LMI>,
+ <CLK_ICN_SBC>;
};
};
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 8f79b4147bba..c8b2944e304a 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -916,7 +916,7 @@
};
sti_uni_player0: sti-uni-player@8d80000 {
- compatible = "st,sti-uni-player";
+ compatible = "st,stih407-uni-player-hdmi";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_0>;
@@ -926,17 +926,13 @@
reg = <0x8d80000 0x158>;
interrupts = <GIC_SPI 84 IRQ_TYPE_NONE>;
dmas = <&fdma0 2 0 1>;
- dai-name = "Uni Player #0 (HDMI)";
dma-names = "tx";
- st,uniperiph-id = <0>;
- st,version = <5>;
- st,mode = "HDMI";
status = "disabled";
};
sti_uni_player1: sti-uni-player@8d81000 {
- compatible = "st,sti-uni-player";
+ compatible = "st,stih407-uni-player-pcm-out";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
@@ -946,17 +942,13 @@
reg = <0x8d81000 0x158>;
interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
dmas = <&fdma0 3 0 1>;
- dai-name = "Uni Player #1 (PIO)";
dma-names = "tx";
- st,uniperiph-id = <1>;
- st,version = <5>;
- st,mode = "PCM";
status = "disabled";
};
sti_uni_player2: sti-uni-player@8d82000 {
- compatible = "st,sti-uni-player";
+ compatible = "st,stih407-uni-player-dac";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
@@ -966,17 +958,13 @@
reg = <0x8d82000 0x158>;
interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
dmas = <&fdma0 4 0 1>;
- dai-name = "Uni Player #1 (DAC)";
dma-names = "tx";
- st,uniperiph-id = <2>;
- st,version = <5>;
- st,mode = "PCM";
status = "disabled";
};
sti_uni_player3: sti-uni-player@8d85000 {
- compatible = "st,sti-uni-player";
+ compatible = "st,stih407-uni-player-spdif";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
@@ -987,38 +975,30 @@
interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
dmas = <&fdma0 7 0 1>;
dma-names = "tx";
- dai-name = "Uni Player #1 (PIO)";
- st,uniperiph-id = <3>;
- st,version = <5>;
- st,mode = "SPDIF";
status = "disabled";
};
sti_uni_reader0: sti-uni-reader@8d83000 {
- compatible = "st,sti-uni-reader";
+ compatible = "st,stih407-uni-reader-pcm_in";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
reg = <0x8d83000 0x158>;
interrupts = <GIC_SPI 87 IRQ_TYPE_NONE>;
dmas = <&fdma0 5 0 1>;
dma-names = "rx";
- dai-name = "Uni Reader #0 (PCM IN)";
- st,version = <3>;
status = "disabled";
};
sti_uni_reader1: sti-uni-reader@8d84000 {
- compatible = "st,sti-uni-reader";
+ compatible = "st,stih407-uni-reader-hdmi";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
reg = <0x8d84000 0x158>;
interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
dmas = <&fdma0 6 0 1>;
dma-names = "rx";
- dai-name = "Uni Reader #1 (HDMI RX)";
- st,version = <3>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index c325cc059ae4..daab16b5ae64 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -1157,7 +1157,7 @@
reg = <0x0923f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 192 IRQ_TYPE_NONE>;
- interrupts-names = "irqmux";
+ interrupt-names = "irqmux";
ranges = <0 0x09230000 0x3000>;
pio40: gpio@09230000 {
diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
index 291ffacbd2e0..fa149837df14 100644
--- a/arch/arm/boot/dts/stih407.dtsi
+++ b/arch/arm/boot/dts/stih407.dtsi
@@ -102,7 +102,7 @@
<&clk_s_d2_quadfs 0>;
};
- sti-hdmi@8d04000 {
+ sti_hdmi: sti-hdmi@8d04000 {
compatible = "st,stih407-hdmi";
reg = <0x8d04000 0x1000>;
reg-names = "hdmi-reg";
diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts
index 7fb507fcba7e..06b0696cb6b8 100644
--- a/arch/arm/boot/dts/stih410-b2260.dts
+++ b/arch/arm/boot/dts/stih410-b2260.dts
@@ -165,6 +165,9 @@
status = "okay";
};
+ sti_uni_player0: sti-uni-player@8d80000 {
+ status = "okay";
+ };
/* SSC11 to HDMI */
hdmiddc: i2c@9541000 {
/* HDMI V1.3a supports Standard mode only */
@@ -174,9 +177,22 @@
status = "okay";
};
- sti-display-subsystem {
- sti_hdmi: sti-hdmi@8d04000 {
- status = "okay";
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "STI-B2260";
+ status = "okay";
+
+ simple-audio-card,dai-link@0 {
+ /* DAC */
+ format = "i2s";
+ mclk-fs = <128>;
+ cpu {
+ sound-dai = <&sti_uni_player0>;
+ };
+
+ codec {
+ sound-dai = <&sti_hdmi>;
+ };
};
};
diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
index 8598effd6c01..07c8ef9d77f6 100644
--- a/arch/arm/boot/dts/stih410-clock.dtsi
+++ b/arch/arm/boot/dts/stih410-clock.dtsi
@@ -208,7 +208,8 @@
"clk-clust-hades",
"clk-hwpe-hades",
"clk-fc-hades";
- clock-critical = <CLK_ICN_CPU>,
+ clock-critical = <CLK_PROC_STFE>,
+ <CLK_ICN_CPU>,
<CLK_TX_ICN_DMU>,
<CLK_EXT2F_A9>,
<CLK_ICN_LMI>,
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index a3ef7341c051..281a12424cf6 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -193,7 +193,7 @@
<&clk_s_d2_quadfs 0>;
};
- sti-hdmi@8d04000 {
+ sti_hdmi: sti-hdmi@8d04000 {
compatible = "st,stih407-hdmi";
reg = <0x8d04000 0x1000>;
reg-names = "hdmi-reg";
diff --git a/arch/arm/boot/dts/stih415-b2000.dts b/arch/arm/boot/dts/stih415-b2000.dts
deleted file mode 100644
index bdfbd3765db2..000000000000
--- a/arch/arm/boot/dts/stih415-b2000.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-/dts-v1/;
-#include "stih415.dtsi"
-#include "stih41x-b2000.dtsi"
-/ {
- model = "STiH415 B2000 Board";
- compatible = "st,stih415-b2000", "st,stih415";
-};
diff --git a/arch/arm/boot/dts/stih415-b2020.dts b/arch/arm/boot/dts/stih415-b2020.dts
deleted file mode 100644
index 71903a87bd31..000000000000
--- a/arch/arm/boot/dts/stih415-b2020.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-/dts-v1/;
-#include "stih415.dtsi"
-#include "stih41x-b2020.dtsi"
-/ {
- model = "STiH415 B2020 Board";
- compatible = "st,stih415-b2020", "st,stih415";
-};
diff --git a/arch/arm/boot/dts/stih415-clock.dtsi b/arch/arm/boot/dts/stih415-clock.dtsi
deleted file mode 100644
index 3ee34514bc4b..000000000000
--- a/arch/arm/boot/dts/stih415-clock.dtsi
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) 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.
- */
-
-#include <dt-bindings/clock/stih415-clks.h>
-
-/ {
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- /*
- * Fixed 30MHz oscillator input to SoC
- */
- clk_sysin: clk-sysin {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <30000000>;
- };
-
- /*
- * ClockGenAs on SASG1
- */
- clockgen-a@fee62000 {
- reg = <0xfee62000 0xb48>;
-
- clk_s_a0_pll: clk-s-a0-pll {
- #clock-cells = <1>;
- compatible = "st,clkgena-plls-c65";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a0-pll0-hs",
- "clk-s-a0-pll0-ls",
- "clk-s-a0-pll1";
- };
-
- clk_s_a0_osc_prediv: clk-s-a0-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c65",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a0-osc-prediv";
- };
-
- clk_s_a0_hs: clk-s-a0-hs {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-hs",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a0_osc_prediv>,
- <&clk_s_a0_pll 0>, /* PLL0 HS */
- <&clk_s_a0_pll 2>; /* PLL1 */
-
- clock-output-names = "clk-s-fdma-0",
- "clk-s-fdma-1",
- ""; /* clk-s-jit-sense */
- /* Fourth output unused */
- };
-
- clk_s_a0_ls: clk-s-a0-ls {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-ls",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a0_osc_prediv>,
- <&clk_s_a0_pll 1>, /* PLL0 LS */
- <&clk_s_a0_pll 2>; /* PLL1 */
-
- clock-output-names = "clk-s-icn-reg-0",
- "clk-s-icn-if-0",
- "clk-s-icn-reg-lp-0",
- "clk-s-emiss",
- "clk-s-eth1-phy",
- "clk-s-mii-ref-out";
- /* Remaining outputs unused */
- };
- };
-
- clockgen-a@fee81000 {
- reg = <0xfee81000 0xb48>;
-
- clk_s_a1_pll: clk-s-a1-pll {
- #clock-cells = <1>;
- compatible = "st,clkgena-plls-c65";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a1-pll0-hs",
- "clk-s-a1-pll0-ls",
- "clk-s-a1-pll1";
- };
-
- clk_s_a1_osc_prediv: clk-s-a1-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c65",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a1-osc-prediv";
- };
-
- clk_s_a1_hs: clk-s-a1-hs {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-hs",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a1_osc_prediv>,
- <&clk_s_a1_pll 0>, /* PLL0 HS */
- <&clk_s_a1_pll 2>; /* PLL1 */
-
- clock-output-names = "", /* Reserved */
- "", /* Reserved */
- "clk-s-stac-phy",
- "clk-s-vtac-tx-phy";
- };
-
- clk_s_a1_ls: clk-s-a1-ls {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-ls",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a1_osc_prediv>,
- <&clk_s_a1_pll 1>, /* PLL0 LS */
- <&clk_s_a1_pll 2>; /* PLL1 */
-
- clock-output-names = "clk-s-icn-if-2",
- "clk-s-card-mmc",
- "clk-s-icn-if-1",
- "clk-s-gmac0-phy",
- "clk-s-nand-ctrl",
- "", /* Reserved */
- "clk-s-mii0-ref-out",
- ""; /* clk-s-stac-sys */
- /* Remaining outputs unused */
- };
- };
-
- /*
- * ClockGenAs on MPE41
- */
- clockgen-a@fde12000 {
- reg = <0xfde12000 0xb50>;
-
- clk_m_a0_pll0: clk-m-a0-pll0 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a0-pll0-phi0",
- "clk-m-a0-pll0-phi1",
- "clk-m-a0-pll0-phi2",
- "clk-m-a0-pll0-phi3";
- };
-
- clk_m_a0_pll1: clk-m-a0-pll1 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a0-pll1-phi0",
- "clk-m-a0-pll1-phi1",
- "clk-m-a0-pll1-phi2",
- "clk-m-a0-pll1-phi3";
- };
-
- clk_m_a0_osc_prediv: clk-m-a0-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c32",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a0-osc-prediv";
- };
-
- clk_m_a0_div0: clk-m-a0-div0 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf0",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 0>, /* PLL0 PHI0 */
- <&clk_m_a0_pll1 0>; /* PLL1 PHI0 */
-
- clock-output-names = "clk-m-apb-pm", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "clk-m-pp-dmu-0",
- "clk-m-pp-dmu-1",
- "clk-m-icm-disp",
- ""; /* Unused */
- };
-
- clk_m_a0_div1: clk-m-a0-div1 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf1",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 1>, /* PLL0 PHI1 */
- <&clk_m_a0_pll1 1>; /* PLL1 PHI1 */
-
- clock-output-names = "", /* Unused */
- "", /* Unused */
- "clk-m-a9-ext2f",
- "clk-m-st40rt",
- "clk-m-st231-dmu-0",
- "clk-m-st231-dmu-1",
- "clk-m-st231-aud",
- "clk-m-st231-gp-0";
- };
-
- clk_m_a0_div2: clk-m-a0-div2 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf2",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 2>, /* PLL0 PHI2 */
- <&clk_m_a0_pll1 2>; /* PLL1 PHI2 */
-
- clock-output-names = "clk-m-st231-gp-1",
- "clk-m-icn-cpu",
- "clk-m-icn-stac",
- "clk-m-icn-dmu-0",
- "clk-m-icn-dmu-1",
- "", /* Unused */
- "", /* Unused */
- ""; /* Unused */
- };
-
- clk_m_a0_div3: clk-m-a0-div3 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf3",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 3>, /* PLL0 PHI3 */
- <&clk_m_a0_pll1 3>; /* PLL1 PHI3 */
-
- clock-output-names = "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "clk-m-icn-eram",
- "clk-m-a9-trace";
- };
- };
-
- clockgen-a@fd6db000 {
- reg = <0xfd6db000 0xb50>;
-
- clk_m_a1_pll0: clk-m-a1-pll0 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a1-pll0-phi0",
- "clk-m-a1-pll0-phi1",
- "clk-m-a1-pll0-phi2",
- "clk-m-a1-pll0-phi3";
- };
-
- clk_m_a1_pll1: clk-m-a1-pll1 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a1-pll1-phi0",
- "clk-m-a1-pll1-phi1",
- "clk-m-a1-pll1-phi2",
- "clk-m-a1-pll1-phi3";
- };
-
- clk_m_a1_osc_prediv: clk-m-a1-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c32",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a1-osc-prediv";
- };
-
- clk_m_a1_div0: clk-m-a1-div0 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf0",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 0>, /* PLL0 PHI0 */
- <&clk_m_a1_pll1 0>; /* PLL1 PHI0 */
-
- clock-output-names = "clk-m-fdma-12",
- "clk-m-fdma-10",
- "clk-m-fdma-11",
- "clk-m-hva-lmi",
- "clk-m-proc-sc",
- "clk-m-tp",
- "clk-m-icn-gpu",
- "clk-m-icn-vdp-0";
- };
-
- clk_m_a1_div1: clk-m-a1-div1 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf1",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 1>, /* PLL0 PHI1 */
- <&clk_m_a1_pll1 1>; /* PLL1 PHI1 */
-
- clock-output-names = "clk-m-icn-vdp-1",
- "clk-m-icn-vdp-2",
- "clk-m-icn-vdp-3",
- "clk-m-prv-t1-bus",
- "clk-m-icn-vdp-4",
- "clk-m-icn-reg-10",
- "", /* Unused */
- ""; /* clk-m-icn-st231 */
- };
-
- clk_m_a1_div2: clk-m-a1-div2 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf2",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 2>, /* PLL0 PHI2 */
- <&clk_m_a1_pll1 2>; /* PLL1 PHI2 */
-
- clock-output-names = "clk-m-fvdp-proc-alt",
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- ""; /* Unused */
- };
-
- clk_m_a1_div3: clk-m-a1-div3 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf3",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 3>, /* PLL0 PHI3 */
- <&clk_m_a1_pll1 3>; /* PLL1 PHI3 */
-
- clock-output-names = "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- ""; /* Unused */
- };
- };
-
- clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2 {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clocks = <&clk_m_a0_div1 2>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
- clockgen-a@fd345000 {
- reg = <0xfd345000 0xb50>;
-
- clk_m_a2_pll0: clk-m-a2-pll0 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a2-pll0-phi0",
- "clk-m-a2-pll0-phi1",
- "clk-m-a2-pll0-phi2",
- "clk-m-a2-pll0-phi3";
- };
-
- clk_m_a2_pll1: clk-m-a2-pll1 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a2-pll1-phi0",
- "clk-m-a2-pll1-phi1",
- "clk-m-a2-pll1-phi2",
- "clk-m-a2-pll1-phi3";
- };
-
- clk_m_a2_osc_prediv: clk-m-a2-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c32",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a2-osc-prediv";
- };
-
- clk_m_a2_div0: clk-m-a2-div0 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf0",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 0>, /* PLL0 PHI0 */
- <&clk_m_a2_pll1 0>; /* PLL1 PHI0 */
-
- clock-output-names = "clk-m-vtac-main-phy",
- "clk-m-vtac-aux-phy",
- "clk-m-stac-phy",
- "clk-m-stac-sys",
- "", /* clk-m-mpestac-pg */
- "", /* clk-m-mpestac-wc */
- "", /* clk-m-mpevtacaux-pg*/
- ""; /* clk-m-mpevtacmain-pg*/
- };
-
- clk_m_a2_div1: clk-m-a2-div1 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf1",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 1>, /* PLL0 PHI1 */
- <&clk_m_a2_pll1 1>; /* PLL1 PHI1 */
-
- clock-output-names = "", /* clk-m-mpevtacrx0-wc */
- "", /* clk-m-mpevtacrx1-wc */
- "clk-m-compo-main",
- "clk-m-compo-aux",
- "clk-m-bdisp-0",
- "clk-m-bdisp-1",
- "clk-m-icn-bdisp-0",
- "clk-m-icn-bdisp-1";
- };
-
- clk_m_a2_div2: clk-m-a2-div2 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf2",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 2>, /* PLL0 PHI2 */
- <&clk_m_a2_pll1 2>; /* PLL1 PHI2 */
-
- clock-output-names = "", /* clk-m-icn-hqvdp0 */
- "", /* clk-m-icn-hqvdp1 */
- "clk-m-icn-compo",
- "", /* clk-m-icn-vdpaux */
- "clk-m-icn-ts",
- "clk-m-icn-reg-lp-10",
- "clk-m-dcephy-impctrl",
- ""; /* Unused */
- };
-
- clk_m_a2_div3: clk-m-a2-div3 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf3",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 3>, /* PLL0 PHI3 */
- <&clk_m_a2_pll1 3>; /* PLL1 PHI3 */
-
- clock-output-names = ""; /* Unused */
- /* Remaining outputs unused */
- };
- };
-
- /*
- * A9 PLL
- */
- clockgen-a9@fdde00d8 {
- reg = <0xfdde00d8 0x70>;
-
- clockgen_a9_pll: clockgen-a9-pll {
- #clock-cells = <1>;
- compatible = "st,stih415-plls-c32-a9", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
- clock-output-names = "clockgen-a9-pll-odf";
- };
- };
-
- /*
- * ARM CPU related clocks
- */
- clk_m_a9: clk-m-a9@fdde00d8 {
- #clock-cells = <0>;
- compatible = "st,stih415-clkgen-a9-mux", "st,clkgen-mux";
- reg = <0xfdde00d8 0x4>;
- clocks = <&clockgen_a9_pll 0>,
- <&clockgen_a9_pll 0>,
- <&clk_m_a0_div1 2>,
- <&clk_m_a9_ext2f_div2>;
- };
-
- /*
- * ARM Peripheral clock for timers
- */
- arm_periph_clk: clk-m-a9-periphs {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clocks = <&clk_m_a9>;
- clock-div = <2>;
- clock-mult = <1>;
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi
deleted file mode 100644
index bd028ce98b61..000000000000
--- a/arch/arm/boot/dts/stih415-pinctrl.dtsi
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-#include "st-pincfg.h"
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-/ {
-
- aliases {
- gpio0 = &pio0;
- gpio1 = &pio1;
- gpio2 = &pio2;
- gpio3 = &pio3;
- gpio4 = &pio4;
- gpio5 = &pio5;
- gpio6 = &pio6;
- gpio7 = &pio7;
- gpio8 = &pio8;
- gpio9 = &pio9;
- gpio10 = &pio10;
- gpio11 = &pio11;
- gpio12 = &pio12;
- gpio13 = &pio13;
- gpio14 = &pio14;
- gpio15 = &pio15;
- gpio16 = &pio16;
- gpio17 = &pio17;
- gpio18 = &pio18;
- gpio19 = &pio100;
- gpio20 = &pio101;
- gpio21 = &pio102;
- gpio22 = &pio103;
- gpio23 = &pio104;
- gpio24 = &pio105;
- gpio25 = &pio106;
- gpio26 = &pio107;
- };
-
- soc {
- pin-controller-sbc {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih415-sbc-pinctrl";
- st,syscfg = <&syscfg_sbc>;
- reg = <0xfe61f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfe610000 0x5000>;
-
- pio0: gpio@fe610000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO0";
- };
- pio1: gpio@fe611000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO1";
- };
- pio2: gpio@fe612000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO2";
- };
- pio3: gpio@fe613000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO3";
- };
- pio4: gpio@fe614000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO4";
- };
-
- sbc_serial1 {
- pinctrl_sbc_serial1:sbc_serial1 {
- st,pins {
- tx = <&pio2 6 ALT3 OUT>;
- rx = <&pio2 7 ALT3 IN>;
- };
- };
- };
-
- keyscan {
- pinctrl_keyscan: keyscan {
- st,pins {
- keyin0 = <&pio0 2 ALT2 IN>;
- keyin1 = <&pio0 3 ALT2 IN>;
- keyin2 = <&pio0 4 ALT2 IN>;
- keyin3 = <&pio2 6 ALT2 IN>;
-
- keyout0 = <&pio1 6 ALT2 OUT>;
- keyout1 = <&pio1 7 ALT2 OUT>;
- keyout2 = <&pio0 6 ALT2 OUT>;
- keyout3 = <&pio2 7 ALT2 OUT>;
- };
- };
- };
-
- sbc_i2c0 {
- pinctrl_sbc_i2c0_default: sbc_i2c0-default {
- st,pins {
- sda = <&pio4 6 ALT1 BIDIR>;
- scl = <&pio4 5 ALT1 BIDIR>;
- };
- };
- };
-
- sbc_i2c1 {
- pinctrl_sbc_i2c1_default: sbc_i2c1-default {
- st,pins {
- sda = <&pio3 2 ALT2 BIDIR>;
- scl = <&pio3 1 ALT2 BIDIR>;
- };
- };
- };
-
- rc{
- pinctrl_ir: ir0 {
- st,pins {
- ir = <&pio4 0 ALT2 IN>;
- };
- };
- };
-
- gmac1 {
- pinctrl_mii1: mii1 {
- st,pins {
- txd0 = <&pio0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txd1 = <&pio0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txd2 = <&pio0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txd3 = <&pio0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txer = <&pio0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txen = <&pio0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
- col = <&pio0 7 ALT1 IN BYPASS 1000>;
- mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
- mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
- crs = <&pio1 2 ALT1 IN BYPASS 1000>;
- mdint = <&pio1 3 ALT1 IN BYPASS 0>;
- rxd0 = <&pio1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxd1 = <&pio1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxd2 = <&pio1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxd3 = <&pio1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxdv = <&pio2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rx_er = <&pio2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
- phyclk = <&pio2 3 ALT1 IN NICLK 1000 CLK_A>;
- };
- };
-
- pinctrl_rgmii1: rgmii1-0 {
- st,pins {
- txd0 = <&pio0 0 ALT1 OUT DE_IO 1000 CLK_A>;
- txd1 = <&pio0 1 ALT1 OUT DE_IO 1000 CLK_A>;
- txd2 = <&pio0 2 ALT1 OUT DE_IO 1000 CLK_A>;
- txd3 = <&pio0 3 ALT1 OUT DE_IO 1000 CLK_A>;
- txen = <&pio0 5 ALT1 OUT DE_IO 0 CLK_A>;
- txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
- mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
- mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
- rxd0 = <&pio1 4 ALT1 IN DE_IO 0 CLK_A>;
- rxd1 = <&pio1 5 ALT1 IN DE_IO 0 CLK_A>;
- rxd2 = <&pio1 6 ALT1 IN DE_IO 0 CLK_A>;
- rxd3 = <&pio1 7 ALT1 IN DE_IO 0 CLK_A>;
-
- rxdv = <&pio2 0 ALT1 IN DE_IO 500 CLK_A>;
- rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
- phyclk = <&pio2 3 ALT4 OUT NICLK 0 CLK_B>;
-
- clk125= <&pio3 7 ALT4 IN NICLK 0 CLK_A>;
- };
- };
- };
- };
-
- pin-controller-front {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih415-front-pinctrl";
- st,syscfg = <&syscfg_front>;
- reg = <0xfee0f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfee00000 0x8000>;
-
- pio5: gpio@fee00000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO5";
- };
- pio6: gpio@fee01000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO6";
- };
- pio7: gpio@fee02000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO7";
- };
- pio8: gpio@fee03000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO8";
- };
- pio9: gpio@fee04000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO9";
- };
- pio10: gpio@fee05000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x5000 0x100>;
- st,bank-name = "PIO10";
- };
- pio11: gpio@fee06000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x6000 0x100>;
- st,bank-name = "PIO11";
- };
- pio12: gpio@fee07000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x7000 0x100>;
- st,bank-name = "PIO12";
- };
-
- i2c0 {
- pinctrl_i2c0_default: i2c0-default {
- st,pins {
- sda = <&pio9 3 ALT1 BIDIR>;
- scl = <&pio9 2 ALT1 BIDIR>;
- };
- };
- };
-
- i2c1 {
- pinctrl_i2c1_default: i2c1-default {
- st,pins {
- sda = <&pio12 1 ALT1 BIDIR>;
- scl = <&pio12 0 ALT1 BIDIR>;
- };
- };
- };
- };
-
- pin-controller-rear {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih415-rear-pinctrl";
- st,syscfg = <&syscfg_rear>;
- reg = <0xfe82f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfe820000 0x8000>;
-
- pio13: gpio@fe820000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO13";
- };
- pio14: gpio@fe821000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO14";
- };
- pio15: gpio@fe822000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO15";
- };
- pio16: gpio@fe823000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO16";
- };
- pio17: gpio@fe824000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO17";
- };
- pio18: gpio@fe825000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x5000 0x100>;
- st,bank-name = "PIO18";
- };
-
- serial2 {
- pinctrl_serial2: serial2-0 {
- st,pins {
- tx = <&pio17 4 ALT2 OUT>;
- rx = <&pio17 5 ALT2 IN>;
- };
- };
- };
-
- gmac0{
- pinctrl_mii0: mii0 {
- st,pins {
- mdint = <&pio13 6 ALT2 IN BYPASS 0>;
- txen = <&pio13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
-
- txd0 = <&pio14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- txd1 = <&pio14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- txd2 = <&pio14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
- txd3 = <&pio14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
-
- txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
- txer = <&pio15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- crs = <&pio15 2 ALT2 IN BYPASS 1000>;
- col = <&pio15 3 ALT2 IN BYPASS 1000>;
- mdio = <&pio15 4 ALT2 OUT BYPASS 3000>;
- mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
-
- rxd0 = <&pio16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxd1 = <&pio16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxd2 = <&pio16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxd3 = <&pio16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxdv = <&pio15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rx_er = <&pio15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxclk = <&pio17 0 ALT2 IN NICLK 0 CLK_A>;
- phyclk = <&pio13 5 ALT2 OUT NICLK 1000 CLK_A>;
-
- };
- };
-
- pinctrl_gmii0: gmii0 {
- st,pins {
- mdint = <&pio13 6 ALT2 IN BYPASS 0>;
- mdio = <&pio15 4 ALT2 OUT BYPASS 3000>;
- mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
- txen = <&pio13 7 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
-
- txd0 = <&pio14 0 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
- txd1 = <&pio14 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
- txd2 = <&pio14 2 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
- txd3 = <&pio14 3 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
- txd4 = <&pio14 4 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
- txd5 = <&pio14 5 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
- txd6 = <&pio14 6 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
- txd7 = <&pio14 7 ALT2 OUT SE_NICLK_IO 3000 CLK_B>;
-
- txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
- txer = <&pio15 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>;
- crs = <&pio15 2 ALT2 IN BYPASS 1000>;
- col = <&pio15 3 ALT2 IN BYPASS 1000>;
- rxdv = <&pio15 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rx_er = <&pio15 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
-
- rxd0 = <&pio16 0 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd1 = <&pio16 1 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd2 = <&pio16 2 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd3 = <&pio16 3 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd4 = <&pio16 4 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd5 = <&pio16 5 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd6 = <&pio16 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
- rxd7 = <&pio16 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>;
-
- rxclk = <&pio17 0 ALT2 IN NICLK 0 CLK_A>;
- clk125 = <&pio17 6 ALT1 IN NICLK 0 CLK_A>;
- phyclk = <&pio13 5 ALT4 OUT NICLK 0 CLK_B>;
-
-
- };
- };
- };
-
- mmc0 {
- pinctrl_mmc0: mmc0 {
- st,pins {
- mmcclk = <&pio13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>;
- data0 = <&pio14 4 ALT4 BIDIR_PU BYPASS 0>;
- data1 = <&pio14 5 ALT4 BIDIR_PU BYPASS 0>;
- data2 = <&pio14 6 ALT4 BIDIR_PU BYPASS 0>;
- data3 = <&pio14 7 ALT4 BIDIR_PU BYPASS 0>;
- cmd = <&pio15 1 ALT4 BIDIR_PU BYPASS 0>;
- wp = <&pio15 3 ALT4 IN>;
- data4 = <&pio16 4 ALT4 BIDIR_PU BYPASS 0>;
- data5 = <&pio16 5 ALT4 BIDIR_PU BYPASS 0>;
- data6 = <&pio16 6 ALT4 BIDIR_PU BYPASS 0>;
- data7 = <&pio16 7 ALT4 BIDIR_PU BYPASS 0>;
- pwr = <&pio17 1 ALT4 OUT>;
- cd = <&pio17 2 ALT4 IN>;
- led = <&pio17 3 ALT4 OUT>;
- };
- };
- };
- };
-
- pin-controller-left {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih415-left-pinctrl";
- st,syscfg = <&syscfg_left>;
- reg = <0xfd6bf080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfd6b0000 0x3000>;
-
- pio100: gpio@fd6b0000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO100";
- };
- pio101: gpio@fd6b1000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO101";
- };
- pio102: gpio@fd6b2000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO102";
- };
- };
-
- pin-controller-right {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih415-right-pinctrl";
- st,syscfg = <&syscfg_right>;
- reg = <0xfd33f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfd330000 0x5000>;
-
- pio103: gpio@fd330000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO103";
- };
- pio104: gpio@fd331000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO104";
- };
- pio105: gpio@fd332000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO105";
- };
- pio106: gpio@fd333000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO106";
- };
- pio107: gpio@fd334000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO107";
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
deleted file mode 100644
index 12427e651e5e..000000000000
--- a/arch/arm/boot/dts/stih415.dtsi
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-#include "stih41x.dtsi"
-#include "stih415-clock.dtsi"
-#include "stih415-pinctrl.dtsi"
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/reset/stih415-resets.h>
-/ {
-
- L2: cache-controller {
- compatible = "arm,pl310-cache";
- reg = <0xfffe2000 0x1000>;
- arm,data-latency = <3 2 2>;
- arm,tag-latency = <1 1 1>;
- cache-unified;
- cache-level = <2>;
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&intc>;
- ranges;
- compatible = "simple-bus";
-
- powerdown: powerdown-controller {
- #reset-cells = <1>;
- compatible = "st,stih415-powerdown";
- };
-
- softreset: softreset-controller {
- #reset-cells = <1>;
- compatible = "st,stih415-softreset";
- };
-
- syscfg_sbc: sbc-syscfg@fe600000{
- compatible = "st,stih415-sbc-syscfg", "syscon";
- reg = <0xfe600000 0xb4>;
- };
-
- syscfg_front: front-syscfg@fee10000{
- compatible = "st,stih415-front-syscfg", "syscon";
- reg = <0xfee10000 0x194>;
- };
-
- syscfg_rear: rear-syscfg@fe830000{
- compatible = "st,stih415-rear-syscfg", "syscon";
- reg = <0xfe830000 0x190>;
- };
-
- /* MPE syscfgs */
- syscfg_left: left-syscfg@fd690000{
- compatible = "st,stih415-left-syscfg", "syscon";
- reg = <0xfd690000 0x78>;
- };
-
- syscfg_right: right-syscfg@fd320000{
- compatible = "st,stih415-right-syscfg", "syscon";
- reg = <0xfd320000 0x180>;
- };
-
- syscfg_system: system-syscfg@fdde0000 {
- compatible = "st,stih415-system-syscfg", "syscon";
- reg = <0xfdde0000 0x15c>;
- };
-
- syscfg_lpm: lpm-syscfg@fe4b5100{
- compatible = "st,stih415-lpm-syscfg", "syscon";
- reg = <0xfe4b5100 0x08>;
- };
-
- serial2: serial@fed32000 {
- compatible = "st,asc";
- status = "disabled";
- reg = <0xfed32000 0x2c>;
- interrupts = <0 197 0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_serial2>;
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- };
-
- /* SBC comms block ASCs in SASG1 */
- sbc_serial1: serial@fe531000 {
- compatible = "st,asc";
- status = "disabled";
- reg = <0xfe531000 0x2c>;
- interrupts = <0 210 0>;
- clocks = <&clk_sysin>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sbc_serial1>;
- };
-
- i2c@fed40000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfed40000 0x110>;
- interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0_default>;
-
- status = "disabled";
- };
-
- i2c@fed41000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfed41000 0x110>;
- interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1_default>;
-
- status = "disabled";
- };
-
- i2c@fe540000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfe540000 0x110>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_sysin>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sbc_i2c0_default>;
-
- status = "disabled";
- };
-
- i2c@fe541000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfe541000 0x110>;
- interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_sysin>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sbc_i2c1_default>;
-
- status = "disabled";
- };
-
- ethernet0: dwmac@fe810000 {
- device_type = "network";
- compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
- status = "disabled";
-
- reg = <0xfe810000 0x8000>;
- reg-names = "stmmaceth";
-
- interrupts = <0 147 0>, <0 148 0>, <0 149 0>;
- interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
- resets = <&softreset STIH415_ETH0_SOFTRESET>;
- reset-names = "stmmaceth";
-
- snps,pbl = <32>;
- snps,mixed-burst;
- snps,force_sf_dma_mode;
-
- st,syscon = <&syscfg_rear 0x148>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mii0>;
- clock-names = "stmmaceth", "sti-ethclk";
- clocks = <&clk_s_a1_ls CLK_ICN_IF_2>, <&clk_s_a1_ls CLK_GMAC0_PHY>;
- };
-
- ethernet1: dwmac@fef08000 {
- device_type = "network";
- compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
- status = "disabled";
- reg = <0xfef08000 0x8000>;
- reg-names = "stmmaceth";
- interrupts = <0 150 0>, <0 151 0>, <0 152 0>;
- interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-
- snps,pbl = <32>;
- snps,mixed-burst;
- snps,force_sf_dma_mode;
-
- st,syscon = <&syscfg_sbc 0x74>;
-
- resets = <&softreset STIH415_ETH1_SOFTRESET>;
- reset-names = "stmmaceth";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mii1>;
- clock-names = "stmmaceth", "sti-ethclk";
- clocks = <&clk_s_a0_ls CLK_ICN_REG>, <&clk_s_a0_ls CLK_ETH1_PHY>;
- };
-
- rc: rc@fe518000 {
- compatible = "st,comms-irb";
- reg = <0xfe518000 0x234>;
- interrupts = <0 203 0>;
- clocks = <&clk_sysin>;
- rx-mode = "infrared";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ir>;
- resets = <&softreset STIH415_IRB_SOFTRESET>;
- };
-
- keyscan: keyscan@fe4b0000 {
- compatible = "st,sti-keyscan";
- status = "disabled";
- reg = <0xfe4b0000 0x2000>;
- interrupts = <GIC_SPI 212 IRQ_TYPE_NONE>;
- clocks = <&clk_sysin>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_keyscan>;
- resets = <&powerdown STIH415_KEYSCAN_POWERDOWN>,
- <&softreset STIH415_KEYSCAN_SOFTRESET>;
- };
-
- mmc0: sdhci@fe81e000 {
- compatible = "st,sdhci";
- status = "disabled";
- reg = <0xfe81e000 0x1000>;
- interrupts = <GIC_SPI 145 IRQ_TYPE_NONE>;
- interrupt-names = "mmcirq";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mmc0>;
- clock-names = "mmc";
- clocks = <&clk_s_a1_ls 1>;
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih416-b2000.dts b/arch/arm/boot/dts/stih416-b2000.dts
deleted file mode 100644
index 488e80a5d69d..000000000000
--- a/arch/arm/boot/dts/stih416-b2000.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-/dts-v1/;
-#include "stih416.dtsi"
-#include "stih41x-b2000.dtsi"
-/ {
- model = "STiH416 B2000";
- compatible = "st,stih416-b2000", "st,stih416";
-};
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
deleted file mode 100644
index 200a81844765..000000000000
--- a/arch/arm/boot/dts/stih416-b2020.dts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-/dts-v1/;
-#include "stih416.dtsi"
-#include "stih41x-b2020.dtsi"
-/ {
- model = "STiH416 B2020";
- compatible = "st,stih416-b2020", "st,stih416";
-
- soc {
- mmc1: sdhci@fe81f000 {
- status = "okay";
- bus-width = <8>;
- non-removable;
- };
-
- miphy365x_phy: phy@fe382000 {
- phy_port0: port@fe382000 {
- st,sata-gen = <3>;
- };
-
- phy_port1: port@fe38a000 {
- st,pcie-tx-pol-inv;
- };
- };
-
- sata0: sata@fe380000{
- status = "okay";
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih416-b2020e.dts b/arch/arm/boot/dts/stih416-b2020e.dts
deleted file mode 100644
index de320cd067de..000000000000
--- a/arch/arm/boot/dts/stih416-b2020e.dts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
- * Author: Lee Jones <lee.jones@linaro.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
- * publishhed by the Free Software Foundation.
- */
-/dts-v1/;
-#include "stih416.dtsi"
-#include "stih41x-b2020.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-/ {
- model = "STiH416 B2020 REV-E";
- compatible = "st,stih416-b2020", "st,stih416";
-
- soc {
- leds {
- compatible = "gpio-leds";
- red {
- label = "Front Panel LED";
- gpios = <&pio4 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "heartbeat";
- };
- green {
- gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
-
- ethernet1: dwmac@fef08000 {
- snps,reset-gpio = <&pio0 7>;
- };
-
- mmc1: sdhci@fe81f000 {
- status = "okay";
- bus-width = <8>;
- non-removable;
- };
-
- miphy365x_phy: phy@fe382000 {
- phy_port0: port@fe382000 {
- st,sata-gen = <3>;
- };
-
- phy_port1: port@fe38a000 {
- st,pcie-tx-pol-inv;
- };
- };
-
- sata0: sata@fe380000{
- status = "okay";
- };
-
- /* SAS PWM Module */
- pwm0: pwm@fed10000 {
- status = "okay";
- };
-
- /* SBC PWM Module */
- pwm1: pwm@fe510000 {
- status = "okay";
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
deleted file mode 100644
index 5b4fb838cddb..000000000000
--- a/arch/arm/boot/dts/stih416-clock.dtsi
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics R&D Limited
- * <stlinux-devel@stlinux.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 <dt-bindings/clock/stih416-clks.h>
-
-/ {
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- /*
- * Fixed 30MHz oscillator inputs to SoC
- */
- clk_sysin: clk-sysin {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <30000000>;
- };
-
- /*
- * ClockGenAs on SASG2
- */
- clockgen-a@fee62000 {
- reg = <0xfee62000 0xb48>;
-
- clk_s_a0_pll: clk-s-a0-pll {
- #clock-cells = <1>;
- compatible = "st,clkgena-plls-c65";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a0-pll0-hs",
- "clk-s-a0-pll0-ls",
- "clk-s-a0-pll1";
- };
-
- clk_s_a0_osc_prediv: clk-s-a0-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c65",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a0-osc-prediv";
- };
-
- clk_s_a0_hs: clk-s-a0-hs {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-hs",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a0_osc_prediv>,
- <&clk_s_a0_pll 0>, /* PLL0 HS */
- <&clk_s_a0_pll 2>; /* PLL1 */
-
- clock-output-names = "clk-s-fdma-0",
- "clk-s-fdma-1",
- ""; /* clk-s-jit-sense */
- /* Fourth output unused */
- };
-
- clk_s_a0_ls: clk-s-a0-ls {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-ls",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a0_osc_prediv>,
- <&clk_s_a0_pll 1>, /* PLL0 LS */
- <&clk_s_a0_pll 2>; /* PLL1 */
-
- clock-output-names = "clk-s-icn-reg-0",
- "clk-s-icn-if-0",
- "clk-s-icn-reg-lp-0",
- "clk-s-emiss",
- "clk-s-eth1-phy",
- "clk-s-mii-ref-out";
- /* Remaining outputs unused */
- };
- };
-
- clockgen-a@fee81000 {
- reg = <0xfee81000 0xb48>;
-
- clk_s_a1_pll: clk-s-a1-pll {
- #clock-cells = <1>;
- compatible = "st,clkgena-plls-c65";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a1-pll0-hs",
- "clk-s-a1-pll0-ls",
- "clk-s-a1-pll1";
- };
-
- clk_s_a1_osc_prediv: clk-s-a1-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c65",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-s-a1-osc-prediv";
- };
-
- clk_s_a1_hs: clk-s-a1-hs {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-hs",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a1_osc_prediv>,
- <&clk_s_a1_pll 0>, /* PLL0 HS */
- <&clk_s_a1_pll 2>; /* PLL1 */
-
- clock-output-names = "", /* Reserved */
- "", /* Reserved */
- "clk-s-stac-phy",
- "clk-s-vtac-tx-phy";
- };
-
- clk_s_a1_ls: clk-s-a1-ls {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c65-ls",
- "st,clkgena-divmux";
-
- clocks = <&clk_s_a1_osc_prediv>,
- <&clk_s_a1_pll 1>, /* PLL0 LS */
- <&clk_s_a1_pll 2>; /* PLL1 */
-
- clock-output-names = "clk-s-icn-if-2",
- "clk-s-card-mmc-0",
- "clk-s-icn-if-1",
- "clk-s-gmac0-phy",
- "clk-s-nand-ctrl",
- "", /* Reserved */
- "clk-s-mii0-ref-out",
- "clk-s-stac-sys",
- "clk-s-card-mmc-1";
- /* Remaining outputs unused */
- };
- };
-
- /*
- * ClockGenAs on MPE42
- */
- clockgen-a@fde12000 {
- reg = <0xfde12000 0xb50>;
-
- clk_m_a0_pll0: clk-m-a0-pll0 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a0-pll0-phi0",
- "clk-m-a0-pll0-phi1",
- "clk-m-a0-pll0-phi2",
- "clk-m-a0-pll0-phi3";
- };
-
- clk_m_a0_pll1: clk-m-a0-pll1 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a0-pll1-phi0",
- "clk-m-a0-pll1-phi1",
- "clk-m-a0-pll1-phi2",
- "clk-m-a0-pll1-phi3";
- };
-
- clk_m_a0_osc_prediv: clk-m-a0-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c32",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a0-osc-prediv";
- };
-
- clk_m_a0_div0: clk-m-a0-div0 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf0",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 0>, /* PLL0 PHI0 */
- <&clk_m_a0_pll1 0>; /* PLL1 PHI0 */
-
- clock-output-names = "", /* Unused */
- "", /* Unused */
- "clk-m-fdma-12",
- "", /* Unused */
- "clk-m-pp-dmu-0",
- "clk-m-pp-dmu-1",
- "clk-m-icm-lmi",
- "clk-m-vid-dmu-0";
- };
-
- clk_m_a0_div1: clk-m-a0-div1 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf1",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 1>, /* PLL0 PHI1 */
- <&clk_m_a0_pll1 1>; /* PLL1 PHI1 */
-
- clock-output-names = "clk-m-vid-dmu-1",
- "", /* Unused */
- "clk-m-a9-ext2f",
- "clk-m-st40rt",
- "clk-m-st231-dmu-0",
- "clk-m-st231-dmu-1",
- "clk-m-st231-aud",
- "clk-m-st231-gp-0";
- };
-
- clk_m_a0_div2: clk-m-a0-div2 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf2",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 2>, /* PLL0 PHI2 */
- <&clk_m_a0_pll1 2>; /* PLL1 PHI2 */
-
- clock-output-names = "clk-m-st231-gp-1",
- "clk-m-icn-cpu",
- "clk-m-icn-stac",
- "clk-m-tx-icn-dmu-0",
- "clk-m-tx-icn-dmu-1",
- "clk-m-tx-icn-ts",
- "clk-m-icn-vdp-0",
- "clk-m-icn-vdp-1";
- };
-
- clk_m_a0_div3: clk-m-a0-div3 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf3",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a0_osc_prediv>,
- <&clk_m_a0_pll0 3>, /* PLL0 PHI3 */
- <&clk_m_a0_pll1 3>; /* PLL1 PHI3 */
-
- clock-output-names = "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "clk-m-icn-vp8",
- "", /* Unused */
- "clk-m-icn-reg-11",
- "clk-m-a9-trace";
- };
- };
-
- clockgen-a@fd6db000 {
- reg = <0xfd6db000 0xb50>;
-
- clk_m_a1_pll0: clk-m-a1-pll0 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a1-pll0-phi0",
- "clk-m-a1-pll0-phi1",
- "clk-m-a1-pll0-phi2",
- "clk-m-a1-pll0-phi3";
- };
-
- clk_m_a1_pll1: clk-m-a1-pll1 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a1-pll1-phi0",
- "clk-m-a1-pll1-phi1",
- "clk-m-a1-pll1-phi2",
- "clk-m-a1-pll1-phi3";
- };
-
- clk_m_a1_osc_prediv: clk-m-a1-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c32",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a1-osc-prediv";
- };
-
- clk_m_a1_div0: clk-m-a1-div0 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf0",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 0>, /* PLL0 PHI0 */
- <&clk_m_a1_pll1 0>; /* PLL1 PHI0 */
-
- clock-output-names = "", /* Unused */
- "clk-m-fdma-10",
- "clk-m-fdma-11",
- "clk-m-hva-alt",
- "clk-m-proc-sc",
- "clk-m-tp",
- "clk-m-rx-icn-dmu-0",
- "clk-m-rx-icn-dmu-1";
- };
-
- clk_m_a1_div1: clk-m-a1-div1 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf1",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 1>, /* PLL0 PHI1 */
- <&clk_m_a1_pll1 1>; /* PLL1 PHI1 */
-
- clock-output-names = "clk-m-rx-icn-ts",
- "clk-m-rx-icn-vdp-0",
- "", /* Unused */
- "clk-m-prv-t1-bus",
- "clk-m-icn-reg-12",
- "clk-m-icn-reg-10",
- "", /* Unused */
- "clk-m-icn-st231";
- };
-
- clk_m_a1_div2: clk-m-a1-div2 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf2",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 2>, /* PLL0 PHI2 */
- <&clk_m_a1_pll1 2>; /* PLL1 PHI2 */
-
- clock-output-names = "clk-m-fvdp-proc-alt",
- "clk-m-icn-reg-13",
- "clk-m-tx-icn-gpu",
- "clk-m-rx-icn-gpu",
- "", /* Unused */
- "", /* Unused */
- "", /* clk-m-apb-pm-12 */
- ""; /* Unused */
- };
-
- clk_m_a1_div3: clk-m-a1-div3 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf3",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a1_osc_prediv>,
- <&clk_m_a1_pll0 3>, /* PLL0 PHI3 */
- <&clk_m_a1_pll1 3>; /* PLL1 PHI3 */
-
- clock-output-names = "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- "", /* Unused */
- ""; /* clk-m-gpu-alt */
- };
- };
-
- clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2 {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clocks = <&clk_m_a0_div1 2>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
- clockgen-a@fd345000 {
- reg = <0xfd345000 0xb50>;
-
- clk_m_a2_pll0: clk-m-a2-pll0 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a2-pll0-phi0",
- "clk-m-a2-pll0-phi1",
- "clk-m-a2-pll0-phi2",
- "clk-m-a2-pll0-phi3";
- };
-
- clk_m_a2_pll1: clk-m-a2-pll1 {
- #clock-cells = <1>;
- compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a2-pll1-phi0",
- "clk-m-a2-pll1-phi1",
- "clk-m-a2-pll1-phi2",
- "clk-m-a2-pll1-phi3";
- };
-
- clk_m_a2_osc_prediv: clk-m-a2-osc-prediv {
- #clock-cells = <0>;
- compatible = "st,clkgena-prediv-c32",
- "st,clkgena-prediv";
-
- clocks = <&clk_sysin>;
-
- clock-output-names = "clk-m-a2-osc-prediv";
- };
-
- clk_m_a2_div0: clk-m-a2-div0 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf0",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 0>, /* PLL0 PHI0 */
- <&clk_m_a2_pll1 0>; /* PLL1 PHI0 */
-
- clock-output-names = "clk-m-vtac-main-phy",
- "clk-m-vtac-aux-phy",
- "clk-m-stac-phy",
- "clk-m-stac-sys",
- "", /* clk-m-mpestac-pg */
- "", /* clk-m-mpestac-wc */
- "", /* clk-m-mpevtacaux-pg*/
- ""; /* clk-m-mpevtacmain-pg*/
- };
-
- clk_m_a2_div1: clk-m-a2-div1 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf1",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 1>, /* PLL0 PHI1 */
- <&clk_m_a2_pll1 1>; /* PLL1 PHI1 */
-
- clock-output-names = "", /* clk-m-mpevtacrx0-wc */
- "", /* clk-m-mpevtacrx1-wc */
- "clk-m-compo-main",
- "clk-m-compo-aux",
- "clk-m-bdisp-0",
- "clk-m-bdisp-1",
- "clk-m-icn-bdisp",
- "clk-m-icn-compo";
- };
-
- clk_m_a2_div2: clk-m-a2-div2 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf2",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 2>, /* PLL0 PHI2 */
- <&clk_m_a2_pll1 2>; /* PLL1 PHI2 */
-
- clock-output-names = "clk-m-icn-vdp-2",
- "", /* Unused */
- "clk-m-icn-reg-14",
- "clk-m-mdtp",
- "clk-m-jpegdec",
- "", /* Unused */
- "clk-m-dcephy-impctrl",
- ""; /* Unused */
- };
-
- clk_m_a2_div3: clk-m-a2-div3 {
- #clock-cells = <1>;
- compatible = "st,clkgena-divmux-c32-odf3",
- "st,clkgena-divmux";
-
- clocks = <&clk_m_a2_osc_prediv>,
- <&clk_m_a2_pll0 3>, /* PLL0 PHI3 */
- <&clk_m_a2_pll1 3>; /* PLL1 PHI3 */
-
- clock-output-names = "", /* Unused */
- ""; /* clk-m-apb-pm-11 */
- /* Remaining outputs unused */
- };
- };
-
- /*
- * A9 PLL
- */
- clockgen-a9@fdde08b0 {
- reg = <0xfdde08b0 0x70>;
-
- clockgen_a9_pll: clockgen-a9-pll {
- #clock-cells = <1>;
- compatible = "st,stih416-plls-c32-a9", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
- clock-output-names = "clockgen-a9-pll-odf";
- };
- };
-
- /*
- * ARM CPU related clocks
- */
- clk_m_a9: clk-m-a9@fdde08ac {
- #clock-cells = <0>;
- compatible = "st,stih416-clkgen-a9-mux", "st,clkgen-mux";
- reg = <0xfdde08ac 0x4>;
- clocks = <&clockgen_a9_pll 0>,
- <&clockgen_a9_pll 0>,
- <&clk_m_a0_div1 2>,
- <&clk_m_a9_ext2f_div2>;
- };
-
- /*
- * ARM Peripheral clock for timers
- */
- arm_periph_clk: clk-m-a9-periphs {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clocks = <&clk_m_a9>;
- clock-div = <2>;
- clock-mult = <1>;
- };
-
- /*
- * Frequency synthesizers on the SASG2
- */
- clockgen_b0: clockgen-b0@fee108b4 {
- #clock-cells = <1>;
- compatible = "st,stih416-quadfs216", "st,quadfs";
- reg = <0xfee108b4 0x44>;
-
- clocks = <&clk_sysin>;
- clock-output-names = "clk-s-usb48",
- "clk-s-dss",
- "clk-s-stfe-frc-2",
- "clk-s-thsens-scard";
- };
-
- clockgen_b1: clockgen-b1@fe8308c4 {
- #clock-cells = <1>;
- compatible = "st,stih416-quadfs216", "st,quadfs";
- reg = <0xfe8308c4 0x44>;
-
- clocks = <&clk_sysin>;
- clock-output-names = "clk-s-pcm-0",
- "clk-s-pcm-1",
- "clk-s-pcm-2",
- "clk-s-pcm-3";
- };
-
- clockgen_c: clockgen-c@fe8307d0 {
- #clock-cells = <1>;
- compatible = "st,stih416-quadfs432", "st,quadfs";
- reg = <0xfe8307d0 0x44>;
-
- clocks = <&clk_sysin>;
- clock-output-names = "clk-s-c-fs0-ch0",
- "clk-s-c-vcc-sd",
- "clk-s-c-fs0-ch2";
- };
-
- clk_s_vcc_hd: clk-s-vcc-hd@fe8308b8 {
- #clock-cells = <0>;
- compatible = "st,stih416-clkgenc-vcc-hd", "st,clkgen-mux";
- reg = <0xfe8308b8 0x4>; /* SYSCFG2558 */
-
- clocks = <&clk_sysin>,
- <&clockgen_c 0>;
- };
-
- /*
- * Add a dummy clock for the HDMI PHY for the VCC input mux
- */
- clk_s_tmds_fromphy: clk-s-tmds-fromphy {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <0>;
- };
-
- clockgen_c_vcc: clockgen-c-vcc@fe8308ac {
- #clock-cells = <1>;
- compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
- reg = <0xfe8308ac 0xc>; /* SYSCFG2555,2556,2557 */
-
- clocks = <&clk_s_vcc_hd>,
- <&clockgen_c 1>,
- <&clk_s_tmds_fromphy>,
- <&clockgen_c 2>;
-
- clock-output-names = "clk-s-pix-hdmi",
- "clk-s-pix-dvo",
- "clk-s-out-dvo",
- "clk-s-pix-hd",
- "clk-s-hddac",
- "clk-s-denc",
- "clk-s-sddac",
- "clk-s-pix-main",
- "clk-s-pix-aux",
- "clk-s-stfe-frc-0",
- "clk-s-ref-mcru",
- "clk-s-slave-mcru",
- "clk-s-tmds-hdmi",
- "clk-s-hdmi-reject-pll",
- "clk-s-thsens";
- };
-
- clockgen_d: clockgen-d@fee107e0 {
- #clock-cells = <1>;
- compatible = "st,stih416-quadfs216", "st,quadfs";
- reg = <0xfee107e0 0x44>;
-
- clocks = <&clk_sysin>;
- clock-output-names = "clk-s-ccsc",
- "clk-s-stfe-frc-1",
- "clk-s-tsout-1",
- "clk-s-mchi";
- };
-
- /*
- * Frequency synthesizers on the MPE42
- */
- clockgen_e: clockgen-e@fd3208bc {
- #clock-cells = <1>;
- compatible = "st,stih416-quadfs660-E", "st,quadfs";
- reg = <0xfd3208bc 0xb0>;
-
- clocks = <&clk_sysin>;
- clock-output-names = "clk-m-pix-mdtp-0",
- "clk-m-pix-mdtp-1",
- "clk-m-pix-mdtp-2",
- "clk-m-mpelpc";
- };
-
- clockgen_f: clockgen-f@fd320878 {
- #clock-cells = <1>;
- compatible = "st,stih416-quadfs660-F", "st,quadfs";
- reg = <0xfd320878 0xf0>;
-
- clocks = <&clk_sysin>;
- clock-output-names = "clk-m-main-vidfs",
- "clk-m-hva-fs",
- "clk-m-fvdp-vcpu",
- "clk-m-fvdp-proc-fs";
- };
-
- clk_m_fvdp_proc: clk-m-fvdp-proc@fd320910 {
- #clock-cells = <0>;
- compatible = "st,stih416-clkgenf-vcc-fvdp", "st,clkgen-mux";
- reg = <0xfd320910 0x4>; /* SYSCFG8580 */
-
- clocks = <&clk_m_a1_div2 0>,
- <&clockgen_f 3>;
- };
-
- clk_m_hva: clk-m-hva@fd690868 {
- #clock-cells = <0>;
- compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux";
- reg = <0xfd690868 0x4>; /* SYSCFG9538 */
-
- clocks = <&clockgen_f 1>,
- <&clk_m_a1_div0 3>;
- };
-
- clk_m_f_vcc_hd: clk-m-f-vcc-hd@fd32086c {
- #clock-cells = <0>;
- compatible = "st,stih416-clkgenf-vcc-hd", "st,clkgen-mux";
- reg = <0xfd32086c 0x4>; /* SYSCFG8539 */
-
- clocks = <&clockgen_c_vcc 7>,
- <&clockgen_f 0>;
- };
-
- clk_m_f_vcc_sd: clk-m-f-vcc-sd@fd32086c {
- #clock-cells = <0>;
- compatible = "st,stih416-clkgenf-vcc-sd", "st,clkgen-mux";
- reg = <0xfd32086c 0x4>; /* SYSCFG8539 */
-
- clocks = <&clockgen_c_vcc 8>,
- <&clockgen_f 1>;
- };
-
- /*
- * Add a dummy clock for the HDMIRx external signal clock
- */
- clk_m_pix_hdmirx_sas: clk-m-pix-hdmirx-sas {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <0>;
- };
-
- clockgen_f_vcc: clockgen-f-vcc@fd32086c {
- #clock-cells = <1>;
- compatible = "st,stih416-clkgenf", "st,clkgen-vcc";
- reg = <0xfd32086c 0xc>; /* SYSCFG8539,8540,8541 */
-
- clocks = <&clk_m_f_vcc_hd>,
- <&clk_m_f_vcc_sd>,
- <&clockgen_f 0>,
- <&clk_m_pix_hdmirx_sas>;
-
- clock-output-names = "clk-m-pix-main-pipe",
- "clk-m-pix-aux-pipe",
- "clk-m-pix-main-cru",
- "clk-m-pix-aux-cru",
- "clk-m-xfer-be-compo",
- "clk-m-xfer-pip-compo",
- "clk-m-xfer-aux-compo",
- "clk-m-vsens",
- "clk-m-pix-hdmirx-0",
- "clk-m-pix-hdmirx-1";
- };
-
- /*
- * DDR PLL
- */
- clockgen-ddr@0xfdde07d8 {
- reg = <0xfdde07d8 0x110>;
-
- clockgen_ddr_pll: clockgen-ddr-pll {
- #clock-cells = <1>;
- compatible = "st,stih416-plls-c32-ddr", "st,clkgen-plls-c32";
-
- clocks = <&clk_sysin>;
- clock-output-names = "clockgen-ddr0",
- "clockgen-ddr1";
- };
- };
-
- /*
- * GPU PLL
- */
- clockgen-gpu@fd68ff00 {
- reg = <0xfd68ff00 0x910>;
-
- clockgen_gpu_pll: clockgen-gpu-pll {
- #clock-cells = <1>;
- compatible = "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32";
-
- clocks = <&clk_sysin>;
- clock-output-names = "clockgen-gpu-pll";
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi
deleted file mode 100644
index 9c97f7e651a0..000000000000
--- a/arch/arm/boot/dts/stih416-pinctrl.dtsi
+++ /dev/null
@@ -1,692 +0,0 @@
-
-/*
- * Copyright (C) 2013 STMicroelectronics Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-#include "st-pincfg.h"
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-/ {
-
- aliases {
- gpio0 = &pio0;
- gpio1 = &pio1;
- gpio2 = &pio2;
- gpio3 = &pio3;
- gpio4 = &pio4;
- gpio5 = &pio40;
- gpio6 = &pio5;
- gpio7 = &pio6;
- gpio8 = &pio7;
- gpio9 = &pio8;
- gpio10 = &pio9;
- gpio11 = &pio10;
- gpio12 = &pio11;
- gpio13 = &pio12;
- gpio14 = &pio30;
- gpio15 = &pio31;
- gpio16 = &pio13;
- gpio17 = &pio14;
- gpio18 = &pio15;
- gpio19 = &pio16;
- gpio20 = &pio17;
- gpio21 = &pio18;
- gpio22 = &pio100;
- gpio23 = &pio101;
- gpio24 = &pio102;
- gpio25 = &pio103;
- gpio26 = &pio104;
- gpio27 = &pio105;
- gpio28 = &pio106;
- gpio29 = &pio107;
- };
-
- soc {
- pin-controller-sbc {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih416-sbc-pinctrl";
- st,syscfg = <&syscfg_sbc>;
- reg = <0xfe61f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfe610000 0x6000>;
-
- pio0: gpio@fe610000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO0";
- };
- pio1: gpio@fe611000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO1";
- };
- pio2: gpio@fe612000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO2";
- };
- pio3: gpio@fe613000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO3";
- };
- pio4: gpio@fe614000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO4";
- };
- pio40: gpio@fe615000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x5000 0x100>;
- st,bank-name = "PIO40";
- st,retime-pin-mask = <0x7f>;
- };
-
- rc{
- pinctrl_ir: ir0 {
- st,pins {
- ir = <&pio4 0 ALT2 IN>;
- };
- };
- };
- sbc_serial1 {
- pinctrl_sbc_serial1: sbc_serial1 {
- st,pins {
- tx = <&pio2 6 ALT3 OUT>;
- rx = <&pio2 7 ALT3 IN>;
- };
- };
- };
-
- keyscan {
- pinctrl_keyscan: keyscan {
- st,pins {
- keyin0 = <&pio0 2 ALT2 IN>;
- keyin1 = <&pio0 3 ALT2 IN>;
- keyin2 = <&pio0 4 ALT2 IN>;
- keyin3 = <&pio2 6 ALT2 IN>;
-
- keyout0 = <&pio1 6 ALT2 OUT>;
- keyout1 = <&pio1 7 ALT2 OUT>;
- keyout2 = <&pio0 6 ALT2 OUT>;
- keyout3 = <&pio2 7 ALT2 OUT>;
- };
- };
- };
-
- sbc_i2c0 {
- pinctrl_sbc_i2c0_default: sbc_i2c0-default {
- st,pins {
- sda = <&pio4 6 ALT1 BIDIR>;
- scl = <&pio4 5 ALT1 BIDIR>;
- };
- };
- };
-
- usb {
- pinctrl_usb3: usb3 {
- st,pins {
- oc-detect = <&pio40 0 ALT1 IN>;
- pwr-enable = <&pio40 1 ALT1 OUT>;
- };
- };
- };
-
- sbc_i2c1 {
- pinctrl_sbc_i2c1_default: sbc_i2c1-default {
- st,pins {
- sda = <&pio3 2 ALT2 BIDIR>;
- scl = <&pio3 1 ALT2 BIDIR>;
- };
- };
- };
-
- gmac1 {
- pinctrl_mii1: mii1 {
- st,pins {
- txd0 = <&pio0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txd1 = <&pio0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txd2 = <&pio0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txd3 = <&pio0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txer = <&pio0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txen = <&pio0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
- txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
- col = <&pio0 7 ALT1 IN BYPASS 1000>;
-
- mdio = <&pio1 0 ALT1 OUT BYPASS 1500>;
- mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
- crs = <&pio1 2 ALT1 IN BYPASS 1000>;
- mdint = <&pio1 3 ALT1 IN BYPASS 0>;
- rxd0 = <&pio1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxd1 = <&pio1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxd2 = <&pio1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxd3 = <&pio1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>;
-
- rxdv = <&pio2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rx_er = <&pio2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
- rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
- phyclk = <&pio2 3 ALT1 OUT NICLK 0 CLK_A>;
- };
- };
- pinctrl_rgmii1: rgmii1-0 {
- st,pins {
- txd0 = <&pio0 0 ALT1 OUT DE_IO 500 CLK_A>;
- txd1 = <&pio0 1 ALT1 OUT DE_IO 500 CLK_A>;
- txd2 = <&pio0 2 ALT1 OUT DE_IO 500 CLK_A>;
- txd3 = <&pio0 3 ALT1 OUT DE_IO 500 CLK_A>;
- txen = <&pio0 5 ALT1 OUT DE_IO 0 CLK_A>;
- txclk = <&pio0 6 ALT1 IN NICLK 0 CLK_A>;
-
- mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
- mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
- rxd0 = <&pio1 4 ALT1 IN DE_IO 500 CLK_A>;
- rxd1 = <&pio1 5 ALT1 IN DE_IO 500 CLK_A>;
- rxd2 = <&pio1 6 ALT1 IN DE_IO 500 CLK_A>;
- rxd3 = <&pio1 7 ALT1 IN DE_IO 500 CLK_A>;
-
- rxdv = <&pio2 0 ALT1 IN DE_IO 500 CLK_A>;
- rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
- phyclk = <&pio2 3 ALT4 OUT NICLK 0 CLK_B>;
-
- clk125= <&pio3 7 ALT4 IN NICLK 0 CLK_A>;
- };
- };
- };
-
- pwm1 {
- pinctrl_pwm1_chan0_default: pwm1-0-default {
- st,pins {
- pwm-out = <&pio3 0 ALT1 OUT>;
- pwm-capturein = <&pio3 2 ALT1 IN>;
-
- };
- };
- pinctrl_pwm1_chan1_default: pwm1-1-default {
- st,pins {
- pwm-out = <&pio4 4 ALT1 OUT>;
- pwm-capturein = <&pio4 3 ALT1 IN>;
- };
- };
- pinctrl_pwm1_chan2_default: pwm1-2-default {
- st,pins {
- pwm-out = <&pio4 6 ALT3 OUT>;
- };
- };
- pinctrl_pwm1_chan3_default: pwm1-3-default {
- st,pins {
- pwm-out = <&pio4 7 ALT3 OUT>;
- };
- };
- };
- };
-
- pin-controller-front {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih416-front-pinctrl";
- st,syscfg = <&syscfg_front>;
- reg = <0xfee0f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfee00000 0x10000>;
-
- pio5: gpio@fee00000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO5";
- };
- pio6: gpio@fee01000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO6";
- };
- pio7: gpio@fee02000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO7";
- };
- pio8: gpio@fee03000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO8";
- };
- pio9: gpio@fee04000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO9";
- };
- pio10: gpio@fee05000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x5000 0x100>;
- st,bank-name = "PIO10";
- };
- pio11: gpio@fee06000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x6000 0x100>;
- st,bank-name = "PIO11";
- };
- pio12: gpio@fee07000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x7000 0x100>;
- st,bank-name = "PIO12";
- };
- pio30: gpio@fee08000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x8000 0x100>;
- st,bank-name = "PIO30";
- };
- pio31: gpio@fee09000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x9000 0x100>;
- st,bank-name = "PIO31";
- };
-
- pwm0 {
- pinctrl_pwm0_chan0_default: pwm0-0-default {
- st,pins {
- pwm-out = <&pio9 7 ALT2 OUT>;
- pwm-capturein = <&pio9 6 ALT2 IN>;
- };
- };
- };
-
- serial2-oe {
- pinctrl_serial2_oe: serial2-1 {
- st,pins {
- output-enable = <&pio11 3 ALT2 OUT>;
- };
- };
- };
-
- i2c0 {
- pinctrl_i2c0_default: i2c0-default {
- st,pins {
- sda = <&pio9 3 ALT1 BIDIR>;
- scl = <&pio9 2 ALT1 BIDIR>;
- };
- };
- };
-
- usb {
- pinctrl_usb0: usb0 {
- st,pins {
- oc-detect = <&pio9 4 ALT1 IN>;
- pwr-enable = <&pio9 5 ALT1 OUT>;
- };
- };
- };
-
-
- i2c1 {
- pinctrl_i2c1_default: i2c1-default {
- st,pins {
- sda = <&pio12 1 ALT1 BIDIR>;
- scl = <&pio12 0 ALT1 BIDIR>;
- };
- };
- };
-
- fsm {
- pinctrl_fsm: fsm {
- st,pins {
- spi-fsm-clk = <&pio12 2 ALT1 OUT>;
- spi-fsm-cs = <&pio12 3 ALT1 OUT>;
- spi-fsm-mosi = <&pio12 4 ALT1 OUT>;
- spi-fsm-miso = <&pio12 5 ALT1 IN>;
- spi-fsm-hol = <&pio12 6 ALT1 OUT>;
- spi-fsm-wp = <&pio12 7 ALT1 OUT>;
- };
- };
- };
- };
-
- pin-controller-rear {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih416-rear-pinctrl";
- st,syscfg = <&syscfg_rear>;
- reg = <0xfe82f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfe820000 0x6000>;
-
- pio13: gpio@fe820000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO13";
- };
- pio14: gpio@fe821000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO14";
- };
- pio15: gpio@fe822000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO15";
- };
- pio16: gpio@fe823000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO16";
- };
- pio17: gpio@fe824000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO17";
- };
- pio18: gpio@fe825000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x5000 0x100>;
- st,bank-name = "PIO18";
- st,retime-pin-mask = <0xf>;
- };
-
- serial2 {
- pinctrl_serial2: serial2-0 {
- st,pins {
- tx = <&pio17 4 ALT2 OUT>;
- rx = <&pio17 5 ALT2 IN>;
- };
- };
- };
-
- gmac0 {
- pinctrl_mii0: mii0 {
- st,pins {
- mdint = <&pio13 6 ALT2 IN BYPASS 0>;
- txen = <&pio13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- txd0 = <&pio14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- txd1 = <&pio14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- txd2 = <&pio14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
- txd3 = <&pio14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
-
- txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
- txer = <&pio15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
- crs = <&pio15 2 ALT2 IN BYPASS 1000>;
- col = <&pio15 3 ALT2 IN BYPASS 1000>;
- mdio= <&pio15 4 ALT2 OUT BYPASS 1500>;
- mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
-
- rxd0 = <&pio16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxd1 = <&pio16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxd2 = <&pio16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxd3 = <&pio16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxdv = <&pio15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rx_er = <&pio15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>;
- rxclk = <&pio17 0 ALT2 IN NICLK 0 CLK_A>;
- phyclk = <&pio13 5 ALT2 OUT NICLK 0 CLK_B>;
- };
- };
-
- pinctrl_gmii0: gmii0 {
- st,pins {
- };
- };
- pinctrl_rgmii0: rgmii0 {
- st,pins {
- phyclk = <&pio13 5 ALT4 OUT NICLK 0 CLK_B>;
- txen = <&pio13 7 ALT2 OUT DE_IO 0 CLK_A>;
- txd0 = <&pio14 0 ALT2 OUT DE_IO 500 CLK_A>;
- txd1 = <&pio14 1 ALT2 OUT DE_IO 500 CLK_A>;
- txd2 = <&pio14 2 ALT2 OUT DE_IO 500 CLK_B>;
- txd3 = <&pio14 3 ALT2 OUT DE_IO 500 CLK_B>;
- txclk = <&pio15 0 ALT2 IN NICLK 0 CLK_A>;
-
- mdio = <&pio15 4 ALT2 OUT BYPASS 0>;
- mdc = <&pio15 5 ALT2 OUT NICLK 0 CLK_B>;
-
- rxdv = <&pio15 6 ALT2 IN DE_IO 500 CLK_A>;
- rxd0 =<&pio16 0 ALT2 IN DE_IO 500 CLK_A>;
- rxd1 =<&pio16 1 ALT2 IN DE_IO 500 CLK_A>;
- rxd2 =<&pio16 2 ALT2 IN DE_IO 500 CLK_A>;
- rxd3 =<&pio16 3 ALT2 IN DE_IO 500 CLK_A>;
- rxclk =<&pio17 0 ALT2 IN NICLK 0 CLK_A>;
-
- clk125=<&pio17 6 ALT1 IN NICLK 0 CLK_A>;
- };
- };
- };
-
- mmc0 {
- pinctrl_mmc0: mmc0 {
- st,pins {
- mmcclk = <&pio13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>;
- data0 = <&pio14 4 ALT4 BIDIR_PU BYPASS 0>;
- data1 = <&pio14 5 ALT4 BIDIR_PU BYPASS 0>;
- data2 = <&pio14 6 ALT4 BIDIR_PU BYPASS 0>;
- data3 = <&pio14 7 ALT4 BIDIR_PU BYPASS 0>;
- cmd = <&pio15 1 ALT4 BIDIR_PU BYPASS 0>;
- wp = <&pio15 3 ALT4 IN>;
- data4 = <&pio16 4 ALT4 BIDIR_PU BYPASS 0>;
- data5 = <&pio16 5 ALT4 BIDIR_PU BYPASS 0>;
- data6 = <&pio16 6 ALT4 BIDIR_PU BYPASS 0>;
- data7 = <&pio16 7 ALT4 BIDIR_PU BYPASS 0>;
- pwr = <&pio17 1 ALT4 OUT>;
- cd = <&pio17 2 ALT4 IN>;
- led = <&pio17 3 ALT4 OUT>;
- };
- };
- };
- mmc1 {
- pinctrl_mmc1: mmc1 {
- st,pins {
- mmcclk = <&pio15 0 ALT3 BIDIR_PU NICLK 0 CLK_B>;
- data0 = <&pio13 7 ALT3 BIDIR_PU BYPASS 0>;
- data1 = <&pio14 1 ALT3 BIDIR_PU BYPASS 0>;
- data2 = <&pio14 2 ALT3 BIDIR_PU BYPASS 0>;
- data3 = <&pio14 3 ALT3 BIDIR_PU BYPASS 0>;
- cmd = <&pio15 4 ALT3 BIDIR_PU BYPASS 0>;
- data4 = <&pio15 6 ALT3 BIDIR_PU BYPASS 0>;
- data5 = <&pio15 7 ALT3 BIDIR_PU BYPASS 0>;
- data6 = <&pio16 0 ALT3 BIDIR_PU BYPASS 0>;
- data7 = <&pio16 1 ALT3 BIDIR_PU BYPASS 0>;
- pwr = <&pio16 2 ALT3 OUT>;
- nreset = <&pio13 6 ALT3 OUT>;
- };
- };
- };
-
- usb {
- pinctrl_usb1: usb1 {
- st,pins {
- oc-detect = <&pio18 0 ALT1 IN>;
- pwr-enable = <&pio18 1 ALT1 OUT>;
- };
- };
- pinctrl_usb2: usb2 {
- st,pins {
- oc-detect = <&pio18 2 ALT1 IN>;
- pwr-enable = <&pio18 3 ALT1 OUT>;
- };
- };
- };
-
- pwm0 {
- pinctrl_pwm0_chan1_default: pwm0-1-default {
- st,pins {
- pwm-out = <&pio13 2 ALT2 OUT>;
- pwm-capturein = <&pio13 1 ALT2 IN>;
- };
- };
- pinctrl_pwm0_chan2_default: pwm0-2-default {
- st,pins {
- pwm-out = <&pio15 2 ALT4 OUT>;
- };
- };
- pinctrl_pwm0_chan3_default: pwm0-3-default {
- st,pins {
- pwm-out = <&pio17 4 ALT1 OUT>;
- };
- };
- };
-
- };
-
- pin-controller-fvdp-fe {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih416-fvdp-fe-pinctrl";
- st,syscfg = <&syscfg_fvdp_fe>;
- reg = <0xfd6bf080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfd6b0000 0x3000>;
-
- pio100: gpio@fd6b0000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO100";
- };
- pio101: gpio@fd6b1000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO101";
- };
- pio102: gpio@fd6b2000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO102";
- };
- };
-
- pin-controller-fvdp-lite {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,stih416-fvdp-lite-pinctrl";
- st,syscfg = <&syscfg_fvdp_lite>;
- reg = <0xfd33f080 0x4>;
- reg-names = "irqmux";
- interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "irqmux";
- ranges = <0 0xfd330000 0x5000>;
-
- pio103: gpio@fd330000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0 0x100>;
- st,bank-name = "PIO103";
- };
- pio104: gpio@fd331000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x1000 0x100>;
- st,bank-name = "PIO104";
- };
- pio105: gpio@fd332000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x2000 0x100>;
- st,bank-name = "PIO105";
- };
- pio106: gpio@fd333000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x3000 0x100>;
- st,bank-name = "PIO106";
- };
-
- pio107: gpio@fd334000 {
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <0x4000 0x100>;
- st,bank-name = "PIO107";
- st,retime-pin-mask = <0xf>;
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
deleted file mode 100644
index fe1f9cf770e4..000000000000
--- a/arch/arm/boot/dts/stih416.dtsi
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Copyright (C) 2012 STMicroelectronics Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-#include "stih41x.dtsi"
-#include "stih416-clock.dtsi"
-#include "stih416-pinctrl.dtsi"
-
-#include <dt-bindings/phy/phy.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/reset/stih416-resets.h>
-#include <dt-bindings/interrupt-controller/irq-st.h>
-/ {
- L2: cache-controller {
- compatible = "arm,pl310-cache";
- reg = <0xfffe2000 0x1000>;
- arm,data-latency = <3 3 3>;
- arm,tag-latency = <2 2 2>;
- cache-unified;
- cache-level = <2>;
- };
-
- arm-pmu {
- compatible = "arm,cortex-a9-pmu";
- interrupt-parent = <&intc>;
- interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&intc>;
- ranges;
- compatible = "simple-bus";
-
- restart {
- compatible = "st,stih416-restart";
- st,syscfg = <&syscfg_sbc>;
- status = "okay";
- };
-
- powerdown: powerdown-controller {
- #reset-cells = <1>;
- compatible = "st,stih416-powerdown";
- };
-
- softreset: softreset-controller {
- #reset-cells = <1>;
- compatible = "st,stih416-softreset";
- };
-
- syscfg_sbc:sbc-syscfg@fe600000{
- compatible = "st,stih416-sbc-syscfg", "syscon";
- reg = <0xfe600000 0x1000>;
- };
-
- syscfg_front:front-syscfg@fee10000{
- compatible = "st,stih416-front-syscfg", "syscon";
- reg = <0xfee10000 0x1000>;
- };
-
- syscfg_rear:rear-syscfg@fe830000{
- compatible = "st,stih416-rear-syscfg", "syscon";
- reg = <0xfe830000 0x1000>;
- };
-
- /* MPE */
- syscfg_fvdp_fe:fvdp-fe-syscfg@fddf0000{
- compatible = "st,stih416-fvdp-fe-syscfg", "syscon";
- reg = <0xfddf0000 0x1000>;
- };
-
- syscfg_fvdp_lite:fvdp-lite-syscfg@fd6a0000{
- compatible = "st,stih416-fvdp-lite-syscfg", "syscon";
- reg = <0xfd6a0000 0x1000>;
- };
-
- syscfg_cpu:cpu-syscfg@fdde0000{
- compatible = "st,stih416-cpu-syscfg", "syscon";
- reg = <0xfdde0000 0x1000>;
- };
-
- syscfg_compo:compo-syscfg@fd320000{
- compatible = "st,stih416-compo-syscfg", "syscon";
- reg = <0xfd320000 0x1000>;
- };
-
- syscfg_transport:transport-syscfg@fd690000{
- compatible = "st,stih416-transport-syscfg", "syscon";
- reg = <0xfd690000 0x1000>;
- };
-
- syscfg_lpm:lpm-syscfg@fe4b5100{
- compatible = "st,stih416-lpm-syscfg", "syscon";
- reg = <0xfe4b5100 0x8>;
- };
-
- irq-syscfg {
- compatible = "st,stih416-irq-syscfg";
- st,syscfg = <&syscfg_cpu>;
- st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
- <ST_IRQ_SYSCFG_PMU_1>;
- st,fiq-device = <ST_IRQ_SYSCFG_DISABLED>,
- <ST_IRQ_SYSCFG_DISABLED>;
- };
-
- serial2: serial@fed32000{
- compatible = "st,asc";
- status = "disabled";
- reg = <0xfed32000 0x2c>;
- interrupts = <0 197 0>;
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_serial2 &pinctrl_serial2_oe>;
- };
-
- /* SBC_UART1 */
- sbc_serial1: serial@fe531000 {
- compatible = "st,asc";
- status = "disabled";
- reg = <0xfe531000 0x2c>;
- interrupts = <0 210 0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sbc_serial1>;
- clocks = <&clk_sysin>;
- };
-
- i2c@fed40000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfed40000 0x110>;
- interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0_default>;
-
- status = "disabled";
- };
-
- i2c@fed41000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfed41000 0x110>;
- interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1_default>;
-
- status = "disabled";
- };
-
- i2c@fe540000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfe540000 0x110>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_sysin>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sbc_i2c0_default>;
-
- status = "disabled";
- };
-
- i2c@fe541000 {
- compatible = "st,comms-ssc4-i2c";
- reg = <0xfe541000 0x110>;
- interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_sysin>;
- clock-names = "ssc";
- clock-frequency = <400000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sbc_i2c1_default>;
-
- status = "disabled";
- };
-
- ethernet0: dwmac@fe810000 {
- device_type = "network";
- compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
- status = "disabled";
- reg = <0xfe810000 0x8000>;
- reg-names = "stmmaceth";
-
- interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
- interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-
- snps,pbl = <32>;
- snps,mixed-burst;
-
- st,syscon = <&syscfg_rear 0x8bc>;
- resets = <&softreset STIH416_ETH0_SOFTRESET>;
- reset-names = "stmmaceth";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mii0>;
- clock-names = "stmmaceth", "sti-ethclk";
- clocks = <&clk_s_a1_ls CLK_ICN_IF_2>, <&clk_s_a1_ls CLK_GMAC0_PHY>;
- };
-
- ethernet1: dwmac@fef08000 {
- device_type = "network";
- compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
- status = "disabled";
- reg = <0xfef08000 0x8000>;
- reg-names = "stmmaceth";
- interrupts = <0 136 0>, <0 137 0>, <0 138 0>;
- interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-
- snps,pbl = <32>;
- snps,mixed-burst;
-
- st,syscon = <&syscfg_sbc 0x7f0>;
-
- resets = <&softreset STIH416_ETH1_SOFTRESET>;
- reset-names = "stmmaceth";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mii1>;
- clock-names = "stmmaceth", "sti-ethclk";
- clocks = <&clk_s_a0_ls CLK_ICN_REG>, <&clk_s_a0_ls CLK_ETH1_PHY>;
- };
-
- rc: rc@fe518000 {
- compatible = "st,comms-irb";
- reg = <0xfe518000 0x234>;
- interrupts = <0 203 0>;
- rx-mode = "infrared";
- clocks = <&clk_sysin>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ir>;
- resets = <&softreset STIH416_IRB_SOFTRESET>;
- };
-
- /* FSM */
- spifsm: spifsm@fe902000 {
- compatible = "st,spi-fsm";
- reg = <0xfe902000 0x1000>;
- pinctrl-0 = <&pinctrl_fsm>;
-
- st,syscfg = <&syscfg_rear>;
- st,boot-device-reg = <0x958>;
- st,boot-device-spi = <0x1a>;
-
- status = "disabled";
- };
-
- keyscan: keyscan@fe4b0000 {
- compatible = "st,sti-keyscan";
- status = "disabled";
- reg = <0xfe4b0000 0x2000>;
- interrupts = <GIC_SPI 212 IRQ_TYPE_NONE>;
- clocks = <&clk_sysin>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_keyscan>;
- resets = <&powerdown STIH416_KEYSCAN_POWERDOWN>,
- <&softreset STIH416_KEYSCAN_SOFTRESET>;
- };
-
- temp0 {
- compatible = "st,stih416-sas-thermal";
- clock-names = "thermal";
- clocks = <&clockgen_c_vcc 14>;
-
- status = "okay";
- };
-
- temp1@fdfe8000 {
- compatible = "st,stih416-mpe-thermal";
- reg = <0xfdfe8000 0x10>;
- clocks = <&clockgen_e 3>;
- clock-names = "thermal";
- interrupts = <GIC_SPI 23 IRQ_TYPE_EDGE_RISING>;
-
- status = "okay";
- };
-
- mmc0: sdhci@fe81e000 {
- compatible = "st,sdhci";
- status = "disabled";
- reg = <0xfe81e000 0x1000>;
- interrupts = <GIC_SPI 127 IRQ_TYPE_NONE>;
- interrupt-names = "mmcirq";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mmc0>;
- clock-names = "mmc";
- clocks = <&clk_s_a1_ls 1>;
- };
-
- mmc1: sdhci@fe81f000 {
- compatible = "st,sdhci";
- status = "disabled";
- reg = <0xfe81f000 0x1000>;
- interrupts = <GIC_SPI 128 IRQ_TYPE_NONE>;
- interrupt-names = "mmcirq";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mmc1>;
- clock-names = "mmc";
- clocks = <&clk_s_a1_ls 8>;
- };
-
- miphy365x_phy: phy@fe382000 {
- compatible = "st,miphy365x-phy";
- st,syscfg = <&syscfg_rear 0x824 0x828>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- phy_port0: port@fe382000 {
- #phy-cells = <1>;
- reg = <0xfe382000 0x100>, <0xfe394000 0x100>;
- reg-names = "sata", "pcie";
- };
-
- phy_port1: port@fe38a000 {
- #phy-cells = <1>;
- reg = <0xfe38a000 0x100>, <0xfe804000 0x100>;
- reg-names = "sata", "pcie";
- };
- };
-
- sata0: sata@fe380000 {
- compatible = "st,sti-ahci";
- reg = <0xfe380000 0x1000>;
- interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>;
- interrupt-names = "hostc";
- phys = <&phy_port0 PHY_TYPE_SATA>;
- phy-names = "sata-phy";
- resets = <&powerdown STIH416_SATA0_POWERDOWN>,
- <&softreset STIH416_SATA0_SOFTRESET>;
- reset-names = "pwr-dwn", "sw-rst";
- clock-names = "ahci_clk";
- clocks = <&clk_s_a0_ls CLK_ICN_REG>;
-
- status = "disabled";
- };
-
- usb2_phy: phy@0 {
- compatible = "st,stih416-usb-phy";
- #phy-cells = <0>;
- st,syscfg = <&syscfg_rear>;
- clocks = <&clk_sysin>;
- clock-names = "osc_phy";
- };
-
- ehci0: usb@fe1ffe00 {
- compatible = "st,st-ehci-300x";
- reg = <0xfe1ffe00 0x100>;
- interrupts = <GIC_SPI 148 IRQ_TYPE_NONE>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb0>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB0_POWERDOWN>,
- <&softreset STIH416_USB0_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ohci0: usb@fe1ffc00 {
- compatible = "st,st-ohci-300x";
- reg = <0xfe1ffc00 0x100>;
- interrupts = <GIC_SPI 149 IRQ_TYPE_NONE>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- status = "okay";
- resets = <&powerdown STIH416_USB0_POWERDOWN>,
- <&softreset STIH416_USB0_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ehci1: usb@fe203e00 {
- compatible = "st,st-ehci-300x";
- reg = <0xfe203e00 0x100>;
- interrupts = <GIC_SPI 150 IRQ_TYPE_NONE>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb1>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB1_POWERDOWN>,
- <&softreset STIH416_USB1_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ohci1: usb@fe203c00 {
- compatible = "st,st-ohci-300x";
- reg = <0xfe203c00 0x100>;
- interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB1_POWERDOWN>,
- <&softreset STIH416_USB1_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ehci2: usb@fe303e00 {
- compatible = "st,st-ehci-300x";
- reg = <0xfe303e00 0x100>;
- interrupts = <GIC_SPI 152 IRQ_TYPE_NONE>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb2>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB2_POWERDOWN>,
- <&softreset STIH416_USB2_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ohci2: usb@fe303c00 {
- compatible = "st,st-ohci-300x";
- reg = <0xfe303c00 0x100>;
- interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB2_POWERDOWN>,
- <&softreset STIH416_USB2_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ehci3: usb@fe343e00 {
- compatible = "st,st-ehci-300x";
- reg = <0xfe343e00 0x100>;
- interrupts = <GIC_SPI 154 IRQ_TYPE_NONE>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb3>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB3_POWERDOWN>,
- <&softreset STIH416_USB3_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- ohci3: usb@fe343c00 {
- compatible = "st,st-ohci-300x";
- reg = <0xfe343c00 0x100>;
- interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>;
- clocks = <&clk_s_a1_ls 0>,
- <&clockgen_b0 0>;
- clock-names = "ic", "clk48";
- phys = <&usb2_phy>;
- phy-names = "usb";
- resets = <&powerdown STIH416_USB3_POWERDOWN>,
- <&softreset STIH416_USB3_SOFTRESET>;
- reset-names = "power", "softreset";
- };
-
- /* SAS PWM Module */
- pwm0: pwm@fed10000 {
- compatible = "st,sti-pwm";
- status = "disabled";
- #pwm-cells = <2>;
- reg = <0xfed10000 0x68>;
- interrupts = <GIC_SPI 200 IRQ_TYPE_NONE>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm0_chan0_default
- &pinctrl_pwm0_chan1_default
- &pinctrl_pwm0_chan2_default
- &pinctrl_pwm0_chan3_default>;
-
- clock-names = "pwm", "capture";
- clocks = <&clk_sysin>, <&clk_s_a0_ls CLK_ICN_REG>;
-
- st,pwm-num-chan = <4>;
- st,capture-num-chan = <2>;
- };
-
- /* SBC PWM Module */
- pwm1: pwm@fe510000 {
- compatible = "st,sti-pwm";
- status = "disabled";
- #pwm-cells = <2>;
- reg = <0xfe510000 0x68>;
- interrupts = <GIC_SPI 202 IRQ_TYPE_NONE>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm1_chan0_default
- /*
- * Shared with SBC_OBS_NOTRST. Don't
- * enable unless you really know what
- * you're doing.
- *
- * &pinctrl_pwm1_chan1_default
- */
- &pinctrl_pwm1_chan2_default
- &pinctrl_pwm1_chan3_default>;
-
- clock-names = "pwm";
- clocks = <&clk_sysin>;
- st,pwm-num-chan = <3>;
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi b/arch/arm/boot/dts/stih41x-b2000.dtsi
deleted file mode 100644
index 9bfa0674b452..000000000000
--- a/arch/arm/boot/dts/stih41x-b2000.dtsi
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
-
- memory{
- device_type = "memory";
- reg = <0x60000000 0x40000000>;
- };
-
- chosen {
- bootargs = "console=ttyAS0,115200 clk_ignore_unused";
- linux,stdout-path = &serial2;
- };
-
- aliases {
- ttyAS0 = &serial2;
- ethernet0 = &ethernet0;
- ethernet1 = &ethernet1;
- };
-
- soc {
- serial2: serial@fed32000 {
- status = "okay";
- };
-
- leds {
- compatible = "gpio-leds";
- fp_led {
- label = "Front Panel LED";
- gpios = <&pio105 7 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "heartbeat";
- };
- };
-
- /* HDMI Tx I2C */
- i2c@fed41000 {
- /* HDMI V1.3a supports Standard mode only */
- clock-frequency = <100000>;
- i2c-min-scl-pulse-width-us = <0>;
- i2c-min-sda-pulse-width-us = <5>;
-
- status = "okay";
- };
-
- ethernet0: dwmac@fe810000 {
- status = "okay";
- phy-mode = "mii";
- pinctrl-0 = <&pinctrl_mii0>;
-
- snps,reset-gpio = <&pio106 2>;
- snps,reset-active-low;
- snps,reset-delays-us = <0 10000 10000>;
- };
-
- ethernet1: dwmac@fef08000 {
- status = "disabled";
- phy-mode = "mii";
- st,tx-retime-src = "txclk";
-
- snps,reset-gpio = <&pio4 7>;
- snps,reset-active-low;
- snps,reset-delays-us = <0 10000 10000>;
- };
-
- keyscan: keyscan@fe4b0000 {
- keypad,num-rows = <4>;
- keypad,num-columns = <4>;
- st,debounce-us = <5000>;
- linux,keymap = < MATRIX_KEY(0x00, 0x00, KEY_F13)
- MATRIX_KEY(0x00, 0x01, KEY_F9)
- MATRIX_KEY(0x00, 0x02, KEY_F5)
- MATRIX_KEY(0x00, 0x03, KEY_F1)
- MATRIX_KEY(0x01, 0x00, KEY_F14)
- MATRIX_KEY(0x01, 0x01, KEY_F10)
- MATRIX_KEY(0x01, 0x02, KEY_F6)
- MATRIX_KEY(0x01, 0x03, KEY_F2)
- MATRIX_KEY(0x02, 0x00, KEY_F15)
- MATRIX_KEY(0x02, 0x01, KEY_F11)
- MATRIX_KEY(0x02, 0x02, KEY_F7)
- MATRIX_KEY(0x02, 0x03, KEY_F3)
- MATRIX_KEY(0x03, 0x00, KEY_F16)
- MATRIX_KEY(0x03, 0x01, KEY_F12)
- MATRIX_KEY(0x03, 0x02, KEY_F8)
- MATRIX_KEY(0x03, 0x03, KEY_F4) >;
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi b/arch/arm/boot/dts/stih41x-b2020.dtsi
deleted file mode 100644
index 322e0e95176c..000000000000
--- a/arch/arm/boot/dts/stih41x-b2020.dtsi
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.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
- * publishhed by the Free Software Foundation.
- */
-#include "stih41x-b2020x.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-/ {
- memory{
- device_type = "memory";
- reg = <0x40000000 0x80000000>;
- };
-
- chosen {
- bootargs = "console=ttyAS0,115200 clk_ignore_unused";
- linux,stdout-path = &sbc_serial1;
- };
-
- aliases {
- ttyAS0 = &sbc_serial1;
- ethernet1 = &ethernet1;
- };
- soc {
- sbc_serial1: serial@fe531000 {
- status = "okay";
- };
-
- leds {
- compatible = "gpio-leds";
- red {
- label = "Front Panel LED";
- gpios = <&pio4 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "heartbeat";
- };
- green {
- gpios = <&pio4 7 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
-
- i2c@fed40000 {
- status = "okay";
- };
-
- /* HDMI Tx I2C */
- i2c@fed41000 {
- /* HDMI V1.3a supports Standard mode only */
- clock-frequency = <100000>;
- i2c-min-scl-pulse-width-us = <0>;
- i2c-min-sda-pulse-width-us = <5>;
-
- status = "okay";
- };
-
- i2c@fe540000 {
- status = "okay";
- };
-
- i2c@fe541000 {
- status = "okay";
- };
-
- ethernet1: dwmac@fef08000 {
- status = "okay";
- phy-mode = "rgmii-id";
- max-speed = <1000>;
- st,tx-retime-src = "clk_125";
- snps,reset-gpio = <&pio3 0>;
- snps,reset-active-low;
- snps,reset-delays-us = <0 10000 10000>;
-
- pinctrl-0 = <&pinctrl_rgmii1>;
- };
-
- mmc0: sdhci@fe81e000 {
- bus-width = <8>;
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih41x-b2020x.dtsi b/arch/arm/boot/dts/stih41x-b2020x.dtsi
deleted file mode 100644
index f797a0607382..000000000000
--- a/arch/arm/boot/dts/stih41x-b2020x.dtsi
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- * Author: Lee Jones <lee.jones@linaro.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
- * publishhed by the Free Software Foundation.
- */
-/ {
- soc {
- mmc0: sdhci@fe81e000 {
- status = "okay";
- };
-
- spifsm: spifsm@fe902000 {
- #address-cells = <1>;
- #size-cells = <1>;
-
- status = "okay";
-
- partition@0 {
- label = "SerialFlash1";
- reg = <0x00000000 0x00500000>;
- };
-
- partition@500000 {
- label = "SerialFlash2";
- reg = <0x00500000 0x00b00000>;
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/stih41x.dtsi b/arch/arm/boot/dts/stih41x.dtsi
deleted file mode 100644
index 5cb0e63376b5..000000000000
--- a/arch/arm/boot/dts/stih41x.dtsi
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2014 STMicroelectronics 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
- * publishhed by the Free Software Foundation.
- */
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0>;
- };
- cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <1>;
- };
- };
-
- intc: interrupt-controller@fffe1000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0xfffe1000 0x1000>,
- <0xfffe0100 0x100>;
- };
-
- scu@fffe0000 {
- compatible = "arm,cortex-a9-scu";
- reg = <0xfffe0000 0x1000>;
- };
-
- timer@fffe0200 {
- interrupt-parent = <&intc>;
- compatible = "arm,cortex-a9-global-timer";
- reg = <0xfffe0200 0x100>;
- interrupts = <1 11 0x04>;
- clocks = <&arm_periph_clk>;
- };
-};
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index ed2b7a99ecff..4b8f62f89664 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -135,6 +135,10 @@
};
};
+ sti_uni_player0: sti-uni-player@8d80000 {
+ status = "okay";
+ };
+
sti_uni_player2: sti-uni-player@8d82000 {
status = "okay";
};
@@ -151,13 +155,26 @@
sound {
compatible = "simple-audio-card";
- simple-audio-card,name = "sti audio card";
+ simple-audio-card,name = "STI-B2120";
status = "okay";
simple-audio-card,dai-link@0 {
+ /* HDMI */
+ format = "i2s";
+ mclk-fs = <128>;
+ cpu {
+ sound-dai = <&sti_uni_player0>;
+ };
+
+ codec {
+ sound-dai = <&sti_hdmi>;
+ };
+ };
+ simple-audio-card,dai-link@1 {
/* DAC */
format = "i2s";
mclk-fs = <256>;
+ frame-inversion = <1>;
cpu {
sound-dai = <&sti_uni_player2>;
};
@@ -166,7 +183,7 @@
sound-dai = <&sti_sasg_codec 1>;
};
};
- simple-audio-card,dai-link@1 {
+ simple-audio-card,dai-link@2 {
/* SPDIF */
format = "left_j";
mclk-fs = <128>;
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 6bfc5959dac3..5436e880e28f 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -47,6 +47,7 @@
/dts-v1/;
#include "stm32f429.dtsi"
+#include <dt-bindings/input/input.h>
/ {
model = "STMicroelectronics STM32429i-EVAL board";
@@ -65,6 +66,10 @@
serial0 = &usart1;
};
+ soc {
+ dma-ranges = <0xc0000000 0x0 0x10000000>;
+ };
+
leds {
compatible = "gpio-leds";
green {
@@ -82,6 +87,23 @@
};
};
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+ button@0 {
+ label = "Wake up";
+ linux,code = <KEY_WAKEUP>;
+ gpios = <&gpioa 0 0>;
+ };
+ button@1 {
+ label = "Tamper";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpioc 13 0>;
+ };
+ };
+
usbotg_hs_phy: usbphy {
#phy-cells = <0>;
compatible = "usb-nop-xceiv";
@@ -94,11 +116,12 @@
clock-frequency = <25000000>;
};
-&ethernet0 {
+&mac {
status = "okay";
- pinctrl-0 = <&ethernet0_mii>;
+ pinctrl-0 = <&ethernet_mii>;
pinctrl-names = "default";
- phy-mode = "mii-id";
+ phy-mode = "mii";
+ phy-handle = <&phy1>;
mdio0 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts
new file mode 100644
index 000000000000..aa03fac1ec55
--- /dev/null
+++ b/arch/arm/boot/dts/stm32746g-eval.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@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 "stm32f746.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "STMicroelectronics STM32746g-EVAL board";
+ compatible = "st,stm32746g-eval", "st,stm32f746";
+
+ chosen {
+ bootargs = "root=/dev/ram";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0xc0000000 0x2000000>;
+ };
+
+ aliases {
+ serial0 = &usart1;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ green {
+ gpios = <&gpiof 10 1>;
+ linux,default-trigger = "heartbeat";
+ };
+ red {
+ gpios = <&gpiob 7 1>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+ button@0 {
+ label = "Wake up";
+ linux,code = <KEY_WAKEUP>;
+ gpios = <&gpioc 13 0>;
+ };
+ };
+};
+
+&clk_hse {
+ clock-frequency = <25000000>;
+};
+
+&usart1 {
+ pinctrl-0 = <&usart1_pins_a>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
index 01408073dd53..7d0415e80668 100644
--- a/arch/arm/boot/dts/stm32f429-disco.dts
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -47,6 +47,7 @@
/dts-v1/;
#include "stm32f429.dtsi"
+#include <dt-bindings/input/input.h>
/ {
model = "STMicroelectronics STM32F429i-DISCO board";
@@ -75,6 +76,18 @@
linux,default-trigger = "heartbeat";
};
};
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+ button@0 {
+ label = "User";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpioa 0 0>;
+ };
+ };
};
&clk_hse {
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 336ee4fb587d..e4dae0eda3cd 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -56,11 +56,21 @@
compatible = "fixed-clock";
clock-frequency = <0>;
};
+
+ clk-lse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk-lsi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
};
soc {
- dma-ranges = <0xc0000000 0x0 0x10000000>;
-
timer2: timer@40000000 {
compatible = "st,stm32-timer";
reg = <0x40000000 0x400>;
@@ -122,6 +132,9 @@
interrupts = <39>;
clocks = <&rcc 0 146>;
status = "disabled";
+ dmas = <&dma1 1 4 0x400 0x0>,
+ <&dma1 3 4 0x400 0x0>;
+ dma-names = "rx", "tx";
};
usart4: serial@40004c00 {
@@ -162,6 +175,9 @@
interrupts = <37>;
clocks = <&rcc 0 164>;
status = "disabled";
+ dmas = <&dma2 2 4 0x400 0x0>,
+ <&dma2 7 4 0x400 0x0>;
+ dma-names = "rx", "tx";
};
usart6: serial@40011400 {
@@ -185,11 +201,18 @@
interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
};
+ pwrcfg: power-config@40007000 {
+ compatible = "syscon";
+ reg = <0x40007000 0x400>;
+ };
+
pin-controller {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32f429-pinctrl";
ranges = <0 0x40020000 0x3000>;
+ interrupt-parent = <&exti>;
+ st,syscfg = <&syscfg 0x8>;
pins-are-numbered;
gpioa: gpio@40020000 {
@@ -313,7 +336,7 @@
};
};
- ethernet0_mii: mii@0 {
+ ethernet_mii: mii@0 {
pins {
pinmux = <STM32F429_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>,
<STM32F429_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>,
@@ -340,6 +363,7 @@
compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
reg = <0x40023800 0x400>;
clocks = <&clk_hse>;
+ st,syscfg = <&pwrcfg>;
};
dma1: dma-controller@40026000 {
@@ -373,24 +397,22 @@
st,mem2mem;
};
- ethernet0: dwmac@40028000 {
+ mac: ethernet@40028000 {
compatible = "st,stm32-dwmac", "snps,dwmac-3.50a";
reg = <0x40028000 0x8000>;
reg-names = "stmmaceth";
- interrupts = <61>, <62>;
- interrupt-names = "macirq", "eth_wake_irq";
- clock-names = "stmmaceth", "tx-clk", "rx-clk";
+ interrupts = <61>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>;
st,syscon = <&syscfg 0x4>;
snps,pbl = <8>;
snps,mixed-burst;
- dma-ranges;
status = "disabled";
};
usbotg_hs: usb@40040000 {
compatible = "snps,dwc2";
- dma-ranges;
reg = <0x40040000 0x40000>;
interrupts = <77>;
clocks = <&rcc 0 29>;
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index e911af836471..8877c00ce8e8 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -64,6 +64,14 @@
aliases {
serial0 = &usart3;
};
+
+ soc {
+ dma-ranges = <0xc0000000 0x0 0x10000000>;
+ };
+};
+
+&rcc {
+ compatible = "st,stm32f469-rcc", "st,stm32f42xx-rcc", "st,stm32-rcc";
};
&clk_hse {
diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
new file mode 100644
index 000000000000..f321ffe87144
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@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 "armv7-m.dtsi"
+#include <dt-bindings/pinctrl/stm32f746-pinfunc.h>
+
+/ {
+ clocks {
+ clk_hse: clk-hse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+ };
+
+ soc {
+ timer2: timer@40000000 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000000 0x400>;
+ interrupts = <28>;
+ clocks = <&rcc 0 128>;
+ status = "disabled";
+ };
+
+ timer3: timer@40000400 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000400 0x400>;
+ interrupts = <29>;
+ clocks = <&rcc 0 129>;
+ status = "disabled";
+ };
+
+ timer4: timer@40000800 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000800 0x400>;
+ interrupts = <30>;
+ clocks = <&rcc 0 130>;
+ status = "disabled";
+ };
+
+ timer5: timer@40000c00 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000c00 0x400>;
+ interrupts = <50>;
+ clocks = <&rcc 0 131>;
+ };
+
+ timer6: timer@40001000 {
+ compatible = "st,stm32-timer";
+ reg = <0x40001000 0x400>;
+ interrupts = <54>;
+ clocks = <&rcc 0 132>;
+ status = "disabled";
+ };
+
+ timer7: timer@40001400 {
+ compatible = "st,stm32-timer";
+ reg = <0x40001400 0x400>;
+ interrupts = <55>;
+ clocks = <&rcc 0 133>;
+ status = "disabled";
+ };
+
+ usart2: serial@40004400 {
+ compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+ reg = <0x40004400 0x400>;
+ interrupts = <38>;
+ clocks = <&rcc 0 145>;
+ status = "disabled";
+ };
+
+ usart3: serial@40004800 {
+ compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+ reg = <0x40004800 0x400>;
+ interrupts = <39>;
+ clocks = <&rcc 0 146>;
+ status = "disabled";
+ };
+
+ usart4: serial@40004c00 {
+ compatible = "st,stm32f7-uart";
+ reg = <0x40004c00 0x400>;
+ interrupts = <52>;
+ clocks = <&rcc 0 147>;
+ status = "disabled";
+ };
+
+ usart5: serial@40005000 {
+ compatible = "st,stm32f7-uart";
+ reg = <0x40005000 0x400>;
+ interrupts = <53>;
+ clocks = <&rcc 0 148>;
+ status = "disabled";
+ };
+
+ usart7: serial@40007800 {
+ compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+ reg = <0x40007800 0x400>;
+ interrupts = <82>;
+ clocks = <&rcc 0 158>;
+ status = "disabled";
+ };
+
+ usart8: serial@40007c00 {
+ compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+ reg = <0x40007c00 0x400>;
+ interrupts = <83>;
+ clocks = <&rcc 0 159>;
+ status = "disabled";
+ };
+
+ usart1: serial@40011000 {
+ compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&rcc 0 164>;
+ status = "disabled";
+ };
+
+ usart6: serial@40011400 {
+ compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+ reg = <0x40011400 0x400>;
+ interrupts = <71>;
+ clocks = <&rcc 0 165>;
+ status = "disabled";
+ };
+
+ syscfg: system-config@40013800 {
+ compatible = "syscon";
+ reg = <0x40013800 0x400>;
+ };
+
+ exti: interrupt-controller@40013c00 {
+ compatible = "st,stm32-exti";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x40013C00 0x400>;
+ interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+ };
+
+ pin-controller {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stm32f746-pinctrl";
+ ranges = <0 0x40020000 0x3000>;
+ interrupt-parent = <&exti>;
+ st,syscfg = <&syscfg 0x8>;
+ pins-are-numbered;
+
+ gpioa: gpio@40020000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x0 0x400>;
+ clocks = <&rcc 0 256>;
+ st,bank-name = "GPIOA";
+ };
+
+ gpiob: gpio@40020400 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x400 0x400>;
+ clocks = <&rcc 0 257>;
+ st,bank-name = "GPIOB";
+ };
+
+ gpioc: gpio@40020800 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x800 0x400>;
+ clocks = <&rcc 0 258>;
+ st,bank-name = "GPIOC";
+ };
+
+ gpiod: gpio@40020c00 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0xc00 0x400>;
+ clocks = <&rcc 0 259>;
+ st,bank-name = "GPIOD";
+ };
+
+ gpioe: gpio@40021000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x1000 0x400>;
+ clocks = <&rcc 0 260>;
+ st,bank-name = "GPIOE";
+ };
+
+ gpiof: gpio@40021400 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x1400 0x400>;
+ clocks = <&rcc 0 261>;
+ st,bank-name = "GPIOF";
+ };
+
+ gpiog: gpio@40021800 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x1800 0x400>;
+ clocks = <&rcc 0 262>;
+ st,bank-name = "GPIOG";
+ };
+
+ gpioh: gpio@40021c00 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x1c00 0x400>;
+ clocks = <&rcc 0 263>;
+ st,bank-name = "GPIOH";
+ };
+
+ gpioi: gpio@40022000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2000 0x400>;
+ clocks = <&rcc 0 264>;
+ st,bank-name = "GPIOI";
+ };
+
+ gpioj: gpio@40022400 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2400 0x400>;
+ clocks = <&rcc 0 265>;
+ st,bank-name = "GPIOJ";
+ };
+
+ gpiok: gpio@40022800 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2800 0x400>;
+ clocks = <&rcc 0 266>;
+ st,bank-name = "GPIOK";
+ };
+
+ usart1_pins_a: usart1@0 {
+ pins1 {
+ pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32F746_PA10_FUNC_USART1_RX>;
+ bias-disable;
+ };
+ };
+ };
+
+ rcc: rcc@40023800 {
+ #clock-cells = <2>;
+ compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
+ reg = <0x40023800 0x400>;
+ clocks = <&clk_hse>;
+ };
+ };
+};
+
+&systick {
+ clocks = <&rcc 1 0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 7e7dfc2b43db..b14a4281058d 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -967,7 +967,8 @@
compatible = "allwinner,sun4i-a10-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <28>;
- clocks = <&apb0_gates 5>;
+ clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index aef91476f9ae..0684d7930d65 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -250,8 +250,8 @@
&spi2 {
pinctrl-names = "default";
- pinctrl-0 = <&spi2_pins_a>,
- <&spi2_cs0_pins_a>;
+ pinctrl-0 = <&spi2_pins_b>,
+ <&spi2_cs0_pins_b>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index c41a2ba34dde..7aa8c7aa0153 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -243,14 +243,14 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
- spi2_pins_a: spi2@0 {
+ spi2_pins_b: spi2@1 {
allwinner,pins = "PB12", "PB13", "PB14";
allwinner,function = "spi2";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
- spi2_cs0_pins_a: spi2_cs0@0 {
+ spi2_cs0_pins_b: spi2_cs0@1 {
allwinner,pins = "PB11";
allwinner,function = "spi2";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index b3c234c65ea1..bb7210e0e4a9 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -72,6 +72,47 @@
default-state = "on";
};
};
+
+ bridge {
+ compatible = "dumb-vga-dac";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ vga_bridge_in: endpoint {
+ remote-endpoint = <&tcon0_out_vga>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ vga_bridge_out: endpoint {
+ remote-endpoint = <&vga_con_in>;
+ };
+ };
+ };
+ };
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_con_in: endpoint {
+ remote-endpoint = <&vga_bridge_out>;
+ };
+ };
+ };
+};
+
+&be0 {
+ status = "okay";
};
&ehci0 {
@@ -211,6 +252,19 @@
status = "okay";
};
+&tcon0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_rgb666_pins>;
+ status = "okay";
+};
+
+&tcon0_out {
+ tcon0_out_vga: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vga_bridge_in>;
+ };
+};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_b>;
diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
index a8b0bcc04514..3d7ff10a48e9 100644
--- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
+++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
@@ -83,22 +83,6 @@
allwinner,pins = "PG3";
};
-&i2c1 {
- icn8318: touchscreen@40 {
- compatible = "chipone,icn8318";
- reg = <0x40>;
- interrupt-parent = <&pio>;
- interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */
- pinctrl-names = "default";
- pinctrl-0 = <&ts_wake_pin_p66>;
- wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
- touchscreen-size-x = <800>;
- touchscreen-size-y = <480>;
- touchscreen-inverted-x;
- touchscreen-swapped-x-y;
- };
-};
-
&mmc2 {
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins_a>;
@@ -121,20 +105,26 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
-
- ts_wake_pin_p66: ts_wake_pin@0 {
- allwinner,pins = "PB3";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
-
};
&reg_usb0_vbus {
gpio = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
};
+&touchscreen {
+ compatible = "chipone,icn8318";
+ reg = <0x40>;
+ /* The P66 uses a different EINT then the reference design */
+ interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */
+ /* The icn8318 binding expects wake-gpios instead of power-gpios */
+ wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <480>;
+ touchscreen-inverted-x;
+ touchscreen-swapped-x-y;
+ status = "okay";
+};
+
&uart1 {
/* The P66 uses the uart pins as gpios */
status = "disabled";
diff --git a/arch/arm/boot/dts/sun5i-gr8-chip-pro.dts b/arch/arm/boot/dts/sun5i-gr8-chip-pro.dts
new file mode 100644
index 000000000000..92a2dc6250a5
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-gr8-chip-pro.dts
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2016 Free Electrons
+ * Copyright 2016 NextThing Co
+ *
+ * Maxime Ripard <maxime.ripard@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 "sun5i-gr8.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>
+
+/ {
+ model = "NextThing C.H.I.P. Pro";
+ compatible = "nextthing,chip-pro", "nextthing,gr8";
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ label = "chip-pro:white:status";
+ gpios = <&axp_gpio 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ mmc0_pwrseq: mmc0_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_reg_on_pin_chip_pro>;
+ reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */
+ };
+};
+
+&codec {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+
+ /*
+ * The interrupt is routed through the "External Fast
+ * Interrupt Request" pin (ball G13 of the module)
+ * directly to the main interrupt controller, without
+ * any other controller interfering.
+ */
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "disabled";
+};
+
+&i2s0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>;
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ mmc-pwrseq = <&mmc0_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+ status = "okay";
+
+ nand@0 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ reg = <0>;
+ allwinner,rb = <0>;
+ nand-ecc-mode = "hw";
+ };
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ usb0_id_pin_chip_pro: usb0-id-pin@0 {
+ allwinner,pins = "PG2";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ wifi_reg_on_pin_chip_pro: wifi-reg-on-pin@0 {
+ allwinner,pins = "PB10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins>;
+ status = "disabled";
+};
+
+&reg_dcdc2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+ regulator-always-on;
+};
+
+&reg_dcdc3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-name = "vdd-sys";
+ regulator-always-on;
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avcc";
+ regulator-always-on;
+};
+
+/*
+ * Both LDO3 and LDO4 are used in parallel to power up the
+ * WiFi/BT chip.
+ */
+&reg_ldo3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-1";
+ regulator-always-on;
+};
+
+&reg_ldo4 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-2";
+ regulator-always-on;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins_a>, <&uart2_cts_rts_pins_a>;
+ status = "disabled";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins_a>, <&uart3_cts_rts_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ /*
+ * The CHIP Pro doesn't have a controllable VBUS, nor does it
+ * have any 5v rail on the board itself.
+ *
+ * If one wants to use it as a true OTG port, it should be
+ * done in the baseboard, and its DT / overlay will add it.
+ */
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_pin_chip_pro>;
+ usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb1_vbus-supply = <&reg_vcc5v0>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-gr8-evb.dts b/arch/arm/boot/dts/sun5i-gr8-evb.dts
index 714381fd64d7..030605aa8065 100644
--- a/arch/arm/boot/dts/sun5i-gr8-evb.dts
+++ b/arch/arm/boot/dts/sun5i-gr8-evb.dts
@@ -75,6 +75,39 @@
brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
default-brightness-level = <8>;
};
+
+ sound-analog {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "gr8-evb-wm8978";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <512>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&wm8978>;
+ };
+ };
+
+ sound-spdif {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "On-board SPDIF";
+
+ simple-audio-card,cpu {
+ sound-dai = <&spdif>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&spdif_out>;
+ };
+ };
+
+ spdif_out: spdif-out {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ };
};
&be0 {
diff --git a/arch/arm/boot/dts/sun5i-gr8.dtsi b/arch/arm/boot/dts/sun5i-gr8.dtsi
index ca54e03ef366..ea86d4d58db6 100644
--- a/arch/arm/boot/dts/sun5i-gr8.dtsi
+++ b/arch/arm/boot/dts/sun5i-gr8.dtsi
@@ -792,7 +792,7 @@
};
i2s0_mclk_pins_a: i2s0-mclk@0 {
- allwinner,pins = "PB6", "PB7", "PB8", "PB9";
+ allwinner,pins = "PB5";
allwinner,function = "i2s0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
@@ -854,6 +854,13 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ pwm1_pins: pwm1 {
+ allwinner,pins = "PG13";
+ allwinner,function = "pwm1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
spdif_tx_pins_a: spdif@0 {
allwinner,pins = "PB10";
allwinner,function = "spdif";
@@ -874,6 +881,34 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ uart2_pins_a: uart2@1 {
+ allwinner,pins = "PD2", "PD3";
+ allwinner,function = "uart2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart2_cts_rts_pins_a: uart2-cts-rts@0 {
+ allwinner,pins = "PD4", "PD5";
+ allwinner,function = "uart2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_a: uart3@1 {
+ allwinner,pins = "PG9", "PG10";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_cts_rts_pins_a: uart3-cts-rts@0 {
+ allwinner,pins = "PG11", "PG12";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
pwm: pwm@01c20e00 {
@@ -978,6 +1013,16 @@
status = "disabled";
};
+ uart3: serial@01c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&apb1_gates 19>;
+ status = "disabled";
+ };
+
i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2ac00 0x400>;
diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
index b68a12374b35..c6da5ad37152 100644
--- a/arch/arm/boot/dts/sun5i-r8-chip.dts
+++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
@@ -56,9 +56,11 @@
aliases {
i2c0 = &i2c0;
+ i2c1 = &i2c1;
i2c2 = &i2c2;
serial0 = &uart1;
serial1 = &uart3;
+ spi0 = &spi2;
};
chosen {
@@ -74,6 +76,20 @@
default-state = "on";
};
};
+
+ mmc0_pwrseq: mmc0_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&chip_wifi_reg_on_pin>;
+ reset-gpios = <&pio 2 19 GPIO_ACTIVE_LOW>; /* PC19 */
+ };
+
+ onewire {
+ compatible = "w1-gpio";
+ gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&chip_w1_pin>;
+ };
};
&be0 {
@@ -112,6 +128,12 @@
#include "axp209.dtsi"
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "disabled";
+};
+
&i2c2 {
pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins_a>;
@@ -131,10 +153,15 @@
};
};
+&mmc0_pins_a {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>;
vmmc-supply = <&reg_vcc3v3>;
+ mmc-pwrseq = <&mmc0_pwrseq>;
bus-width = <4>;
non-removable;
status = "okay";
@@ -156,12 +183,26 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ chip_wifi_reg_on_pin: chip_wifi_reg_on_pin@0 {
+ allwinner,pins = "PC19";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
chip_id_det_pin: chip_id_det_pin@0 {
allwinner,pins = "PG2";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ chip_w1_pin: chip_w1_pin@0 {
+ allwinner,pins = "PD2";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
};
&reg_dcdc2 {
@@ -189,6 +230,28 @@
regulator-always-on;
};
+/*
+ * Both LDO3 and LDO4 are used in parallel to power up the WiFi/BT
+ * Chip.
+ *
+ * If those are not enabled, the SDIO part will not enumerate, and
+ * since there's no way currently to pass DT infos to an SDIO device,
+ * we cannot really do better than this ugly hack for now.
+ */
+&reg_ldo3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-1";
+ regulator-always-on;
+};
+
+&reg_ldo4 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-2";
+ regulator-always-on;
+};
+
&reg_ldo5 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -202,6 +265,12 @@
status = "okay";
};
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "disabled";
+};
+
&tcon0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
index 20cc940f5f91..82f87cdcd164 100644
--- a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
@@ -41,6 +41,7 @@
*/
#include "sunxi-reference-design-tablet.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>
/ {
@@ -84,6 +85,23 @@
};
&i2c1 {
+ /*
+ * The gsl1680 is rated at 400KHz and it will not work reliable at
+ * 100KHz, this has been confirmed on multiple different q8 tablets.
+ * All other devices on this bus are also rated for 400KHz.
+ */
+ clock-frequency = <400000>;
+
+ touchscreen: touchscreen {
+ interrupt-parent = <&pio>;
+ interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>; /* EINT11 (PG11) */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_power_pin>;
+ power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
+ /* Tablet dts must provide reg and compatible */
+ status = "disabled";
+ };
+
pcf8563: rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
@@ -125,6 +143,13 @@
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
+ ts_power_pin: ts_power_pin {
+ pins = "PB3";
+ function = "gpio_out";
+ drive-strength = <10>;
+ bias-disable;
+ };
+
usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
allwinner,pins = "PG1";
allwinner,function = "gpio_in";
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index e374f4fc8073..b0fca4ef4dae 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -547,7 +547,8 @@
pio: pinctrl@01c20800 {
reg = <0x01c20800 0x400>;
interrupts = <28>;
- clocks = <&apb0_gates 5>;
+ clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
@@ -574,6 +575,16 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ lcd_rgb565_pins: lcd_rgb565@0 {
+ allwinner,pins = "PD3", "PD4", "PD5", "PD6", "PD7",
+ "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
+ "PD19", "PD20", "PD21", "PD22", "PD23",
+ "PD24", "PD25", "PD26", "PD27";
+ allwinner,function = "lcd0";
+ 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";
@@ -591,6 +602,20 @@
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
+ spi2_pins_a: spi2@0 {
+ allwinner,pins = "PE1", "PE2", "PE3";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_cs0_pins_a: spi2-cs0@0 {
+ allwinner,pins = "PE0";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
uart3_pins_a: uart3@0 {
allwinner,pins = "PG9", "PG10";
allwinner,function = "uart3";
diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 9a74637f677f..735914f6ae44 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -63,12 +63,79 @@
stdout-path = "serial0:115200n8";
};
+ vga-connector {
+ compatible = "vga-connector";
+
+ port {
+ vga_con_in: endpoint {
+ remote-endpoint = <&vga_dac_out>;
+ };
+ };
+ };
+
+ vga-dac {
+ compatible = "dumb-vga-dac";
+ vdd-supply = <&reg_vga_3v3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ vga_dac_in: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&tcon0_out_vga>;
+ };
+ };
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ vga_dac_out: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vga_con_in>;
+ };
+ };
+ };
+ };
+
+ reg_vga_3v3: vga_3v3_regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vga-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&pio 7 25 GPIO_ACTIVE_HIGH>; /* PH25 */
+ };
+
wifi_pwrseq: wifi_pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 */
};
};
+&codec {
+ allwinner,audio-routing =
+ "Headphone", "HP",
+ "Speaker", "LINEOUT",
+ "LINEIN", "Line In",
+ "MIC1", "Mic",
+ "MIC2", "Headset Mic",
+ "Mic", "MBIAS",
+ "Headset Mic", "HBIAS";
+ allwinner,pa-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&reg_dcdc3>;
};
@@ -245,6 +312,19 @@
status = "okay";
};
+&tcon0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd0_rgb888_pins>;
+ status = "okay";
+};
+
+&tcon0_out {
+ tcon0_out_vga: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vga_dac_in>;
+ };
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index ce1960453a0b..2b26175d55d1 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -231,6 +231,11 @@
};
};
+ de: display-engine {
+ compatible = "allwinner,sun6i-a31-display-engine";
+ allwinner,pipelines = <&fe0>;
+ };
+
soc@01c00000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -246,6 +251,44 @@
#dma-cells = <1>;
};
+ tcon0: lcd-controller@01c0c000 {
+ compatible = "allwinner,sun6i-a31-tcon";
+ reg = <0x01c0c000 0x1000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&ccu RST_AHB1_LCD0>;
+ reset-names = "lcd";
+ clocks = <&ccu CLK_AHB1_LCD0>,
+ <&ccu CLK_LCD0_CH0>,
+ <&ccu CLK_LCD0_CH1>;
+ clock-names = "ahb",
+ "tcon-ch0",
+ "tcon-ch1";
+ clock-output-names = "tcon0-pixel-clock";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tcon0_in: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ tcon0_in_drc0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&drc0_out_tcon0>;
+ };
+ };
+
+ tcon0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+ };
+ };
+
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun7i-a20-mmc";
reg = <0x01c0f000 0x1000>;
@@ -428,19 +471,55 @@
<GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_APB1_PIO>;
+ clocks = <&ccu CLK_APB1_PIO>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
#gpio-cells = <3>;
- uart0_pins_a: uart0@0 {
- allwinner,pins = "PH20", "PH21";
- allwinner,function = "uart0";
+ gmac_pins_gmii_a: gmac_gmii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2", "PA3",
+ "PA4", "PA5", "PA6", "PA7",
+ "PA8", "PA9", "PA10", "PA11",
+ "PA12", "PA13", "PA14", "PA15",
+ "PA16", "PA17", "PA18", "PA19",
+ "PA20", "PA21", "PA22", "PA23",
+ "PA24", "PA25", "PA26", "PA27";
+ allwinner,function = "gmac";
+ /*
+ * data lines in GMII mode run at 125MHz and
+ * might need a higher signal drive strength
+ */
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ gmac_pins_mii_a: gmac_mii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2", "PA3",
+ "PA8", "PA9", "PA11",
+ "PA12", "PA13", "PA14", "PA19",
+ "PA20", "PA21", "PA22", "PA23",
+ "PA24", "PA26", "PA27";
+ allwinner,function = "gmac";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ gmac_pins_rgmii_a: gmac_rgmii@0 {
+ allwinner,pins = "PA0", "PA1", "PA2", "PA3",
+ "PA9", "PA10", "PA11",
+ "PA12", "PA13", "PA14", "PA19",
+ "PA20", "PA25", "PA26", "PA27";
+ allwinner,function = "gmac";
+ /*
+ * data lines in RGMII mode use DDR mode
+ * and need a higher signal drive strength
+ */
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PH14", "PH15";
allwinner,function = "i2c0";
@@ -462,6 +541,19 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ lcd0_rgb888_pins: lcd0_rgb888 {
+ allwinner,pins = "PD0", "PD1", "PD2", "PD3",
+ "PD4", "PD5", "PD6", "PD7",
+ "PD8", "PD9", "PD10", "PD11",
+ "PD12", "PD13", "PD14", "PD15",
+ "PD16", "PD17", "PD18", "PD19",
+ "PD20", "PD21", "PD22", "PD23",
+ "PD24", "PD25", "PD26", "PD27";
+ allwinner,function = "lcd0";
+ 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";
@@ -506,47 +598,12 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
- gmac_pins_mii_a: gmac_mii@0 {
- allwinner,pins = "PA0", "PA1", "PA2", "PA3",
- "PA8", "PA9", "PA11",
- "PA12", "PA13", "PA14", "PA19",
- "PA20", "PA21", "PA22", "PA23",
- "PA24", "PA26", "PA27";
- allwinner,function = "gmac";
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PH20", "PH21";
+ allwinner,function = "uart0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
-
- gmac_pins_gmii_a: gmac_gmii@0 {
- allwinner,pins = "PA0", "PA1", "PA2", "PA3",
- "PA4", "PA5", "PA6", "PA7",
- "PA8", "PA9", "PA10", "PA11",
- "PA12", "PA13", "PA14", "PA15",
- "PA16", "PA17", "PA18", "PA19",
- "PA20", "PA21", "PA22", "PA23",
- "PA24", "PA25", "PA26", "PA27";
- allwinner,function = "gmac";
- /*
- * data lines in GMII mode run at 125MHz and
- * might need a higher signal drive strength
- */
- allwinner,drive = <SUN4I_PINCTRL_30_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
-
- gmac_pins_rgmii_a: gmac_rgmii@0 {
- allwinner,pins = "PA0", "PA1", "PA2", "PA3",
- "PA9", "PA10", "PA11",
- "PA12", "PA13", "PA14", "PA19",
- "PA20", "PA25", "PA26", "PA27";
- allwinner,function = "gmac";
- /*
- * data lines in RGMII mode use DDR mode
- * and need a higher signal drive strength
- */
- allwinner,drive = <SUN4I_PINCTRL_40_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
};
timer@01c20c00 {
@@ -728,6 +785,19 @@
reset-names = "ahb";
};
+ codec: codec@01c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun6i-a31-codec";
+ reg = <0x01c22c00 0x400>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_APB1_CODEC>, <&ccu CLK_CODEC>;
+ clock-names = "apb", "codec";
+ resets = <&ccu RST_APB1_CODEC>;
+ dmas = <&dma 15>, <&dma 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
timer@01c60000 {
compatible = "allwinner,sun6i-a31-hstimer",
"allwinner,sun7i-a20-hstimer";
@@ -799,6 +869,115 @@
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
+ fe0: display-frontend@01e00000 {
+ compatible = "allwinner,sun6i-a31-display-frontend";
+ reg = <0x01e00000 0x20000>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_AHB1_FE0>, <&ccu CLK_FE0>,
+ <&ccu CLK_DRAM_FE0>;
+ clock-names = "ahb", "mod",
+ "ram";
+ resets = <&ccu RST_AHB1_FE0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ fe0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ fe0_out_be0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&be0_in_fe0>;
+ };
+ };
+ };
+ };
+
+ be0: display-backend@01e60000 {
+ compatible = "allwinner,sun6i-a31-display-backend";
+ reg = <0x01e60000 0x10000>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_AHB1_BE0>, <&ccu CLK_BE0>,
+ <&ccu CLK_DRAM_BE0>;
+ clock-names = "ahb", "mod",
+ "ram";
+ resets = <&ccu RST_AHB1_BE0>;
+
+ assigned-clocks = <&ccu CLK_BE0>;
+ assigned-clock-rates = <300000000>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ be0_in: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ be0_in_fe0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&fe0_out_be0>;
+ };
+ };
+
+ be0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ be0_out_drc0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&drc0_in_be0>;
+ };
+ };
+ };
+ };
+
+ drc0: drc@01e70000 {
+ compatible = "allwinner,sun6i-a31-drc";
+ reg = <0x01e70000 0x10000>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_AHB1_DRC0>, <&ccu CLK_IEP_DRC0>,
+ <&ccu CLK_DRAM_DRC0>;
+ clock-names = "ahb", "mod",
+ "ram";
+ resets = <&ccu RST_AHB1_DRC0>;
+
+ assigned-clocks = <&ccu CLK_IEP_DRC0>;
+ assigned-clock-rates = <300000000>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ drc0_in: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ drc0_in_be0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&be0_out_drc0>;
+ };
+ };
+
+ drc0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ drc0_out_tcon0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&tcon0_in_drc0>;
+ };
+ };
+ };
+ };
+
rtc: rtc@01f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
@@ -886,7 +1065,8 @@
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>;
+ clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
resets = <&apb0_rst 0>;
gpio-controller;
interrupt-controller;
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
index 6ead2f5c847a..c35ec112f5a0 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -65,6 +65,14 @@
};
};
+&codec {
+ allwinner,audio-routing =
+ "Line Out", "LINEOUT",
+ "MIC1", "Mic",
+ "Mic", "MBIAS";
+ status = "okay";
+};
+
&ehci0 {
/* USB 2.0 4 port hub IC */
status = "okay";
diff --git a/arch/arm/boot/dts/sun6i-a31s.dtsi b/arch/arm/boot/dts/sun6i-a31s.dtsi
index c17a32771b98..97e2c51d0aea 100644
--- a/arch/arm/boot/dts/sun6i-a31s.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31s.dtsi
@@ -48,6 +48,14 @@
#include "sun6i-a31.dtsi"
+&de {
+ compatible = "allwinner,sun6i-a31s-display-engine";
+};
+
&pio {
compatible = "allwinner,sun6i-a31s-pinctrl";
};
+
+&tcon0 {
+ compatible = "allwinner,sun6i-a31s-tcon";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
index ba5bca0fe997..532f1a160560 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
@@ -105,6 +105,10 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
@@ -132,16 +136,14 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-
- interrupt-controller;
- #interrupt-cells = <1>;
};
};
+#include "axp209.dtsi"
+
&ir0 {
pinctrl-names = "default";
pinctrl-0 = <&ir0_rx_pins_a>;
@@ -167,7 +169,7 @@
mmc-pwrseq = <&mmc3_pwrseq>;
bus-width = <4>;
non-removable;
- enable-sdio-wakeup;
+ wakeup-source;
status = "okay";
brcmf: bcrmf@1 {
@@ -192,6 +194,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
gmac_power_pin_bpi_m1p: gmac_power_pin@0 {
allwinner,pins = "PH23";
@@ -222,8 +228,54 @@
};
};
+&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_usb0_vbus {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
status = "okay";
};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ /* VBUS on usb host ports are tied to DC5V and therefore always on */
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
index 23aacce4d6c7..134e0c1b129d 100644
--- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
@@ -88,6 +88,10 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&codec {
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 94cf5a1c7172..f7db067b0de0 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -1085,7 +1085,8 @@
compatible = "allwinner,sun7i-a20-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 5>;
+ clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 300a1bd5a6ec..e4991a78ad73 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -266,7 +266,8 @@
/* compatible gets set in SoC specific dtsi file */
reg = <0x01c20800 0x400>;
/* interrupts get set in SoC specific dtsi file */
- clocks = <&ccu CLK_BUS_PIO>;
+ clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
@@ -575,7 +576,8 @@
compatible = "allwinner,sun8i-a23-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>;
+ clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
resets = <&apb0_rst 0>;
gpio-controller;
interrupt-controller;
diff --git a/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts b/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts
index a86cbedda34c..21bb291b9568 100644
--- a/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts
+++ b/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts
@@ -98,13 +98,6 @@
};
};
-&reg_ldo_io1 {
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-name = "vcc-touchscreen";
- status = "okay";
-};
-
&touchscreen {
reg = <0x40>;
compatible = "silead,gsl1680";
diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index fef6abc0a703..71bb9418c5f9 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -213,6 +213,11 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
&usbphy {
status = "okay";
usb1_vbus-supply = <&reg_vcc5v0>; /* USB1 VBUS is always on */
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
new file mode 100644
index 000000000000..ec63d104b404
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 Milo Kim <woogyom.kim@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 "sun8i-h3-nanopi.dtsi"
+
+/ {
+ model = "FriendlyArm NanoPi M1";
+ compatible = "friendlyarm,nanopi-m1", "allwinner,sun8i-h3";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ehci2 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&ohci2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
index 3d64cafc1e90..8d2cc6e9a03f 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
@@ -40,86 +40,9 @@
* 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>
+#include "sun8i-h3-nanopi.dtsi"
/ {
model = "FriendlyARM NanoPi NEO";
compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3";
-
- aliases {
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&leds_opc>, <&leds_r_opc>;
-
- pwr {
- label = "nanopi:green:pwr";
- gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
- default-state = "on";
- };
-
- status {
- label = "nanopi:blue:status";
- gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>; /* PA10 */
- };
- };
-};
-
-&ehci3 {
- status = "okay";
-};
-
-&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";
-};
-
-&ohci3 {
- status = "okay";
-};
-
-&pio {
- leds_opc: led-pins {
- allwinner,pins = "PA10";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
-};
-
-&r_pio {
- leds_r_opc: led-pins {
- allwinner,pins = "PL10";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins_a>;
- status = "okay";
-};
-
-&usbphy {
- /* USB VBUS is always on */
- status = "okay";
};
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
new file mode 100644
index 000000000000..8038aa29a5a7
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 James Pettigrew <james@innovum.com.au>
+ * Copyright (C) 2016 Milo Kim <woogyom.kim@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/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_npi>, <&leds_r_npi>;
+
+ status {
+ label = "nanopi:blue:status";
+ gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ pwr {
+ label = "nanopi:green:pwr";
+ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ r_gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "k1";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sw_r_npi>;
+
+ k1@0 {
+ label = "k1";
+ linux,code = <KEY_POWER>;
+ gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&ehci3 {
+ status = "okay";
+};
+
+&mmc0 {
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+ status = "okay";
+ vmmc-supply = <&reg_vcc3v3>;
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&pio {
+ leds_npi: led_pins@0 {
+ allwinner,pins = "PA10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&r_pio {
+ leds_r_npi: led_pins@0 {
+ allwinner,pins = "PL10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ sw_r_npi: key_pins@0 {
+ allwinner,pins = "PL3";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index f4ba088b225e..6c14a6f72820 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -321,7 +321,8 @@
reg = <0x01c20800 0x400>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_BUS_PIO>;
+ clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
@@ -381,6 +382,20 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ spi0_pins: spi0 {
+ allwinner,pins = "PC0", "PC1", "PC2", "PC3";
+ allwinner,function = "spi0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi1_pins: spi1 {
+ allwinner,pins = "PA15", "PA16", "PA14", "PA13";
+ allwinner,function = "spi1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
uart0_pins_a: uart0@0 {
allwinner,pins = "PA4", "PA5";
allwinner,function = "uart0";
@@ -425,6 +440,38 @@
clocks = <&osc24M>;
};
+ spi0: spi@01c68000 {
+ compatible = "allwinner,sun8i-h3-spi";
+ reg = <0x01c68000 0x1000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma 23>, <&dma 23>;
+ dma-names = "rx", "tx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ resets = <&ccu RST_BUS_SPI0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@01c69000 {
+ compatible = "allwinner,sun8i-h3-spi";
+ reg = <0x01c69000 0x1000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
+ clock-names = "ahb", "mod";
+ dmas = <&dma 24>, <&dma 24>;
+ dma-names = "rx", "tx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ resets = <&ccu RST_BUS_SPI1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
wdt0: watchdog@01c20ca0 {
compatible = "allwinner,sun6i-a31-wdt";
reg = <0x01c20ca0 0x20>;
@@ -568,7 +615,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>;
+ clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index 08cd00143635..69bc0cd26ca7 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -209,6 +209,13 @@
status = "okay";
};
+&reg_ldo_io1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-touchscreen";
+ status = "okay";
+};
+
&reg_rtc_ldo {
regulator-name = "vcc-rtc";
};
diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
index 439847acd41e..67b02fe7f11c 100644
--- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
+++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
@@ -76,6 +76,14 @@
gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
};
};
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&ac100_rtc 1>;
+ clock-names = "ext_clock";
+ /* enables internal regulator and de-asserts reset */
+ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
+ };
};
&mmc0 {
@@ -88,6 +96,21 @@
status = "okay";
};
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>, <&wifi_en_pin_cubieboard4>;
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_cldo3>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&mmc1_pins {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
&mmc2 {
pinctrl-names = "default";
pinctrl-0 = <&mmc2_8bit_pins>;
@@ -128,6 +151,15 @@
status = "okay";
};
+&r_pio {
+ wifi_en_pin_cubieboard4: wifi_en_pin@0 {
+ allwinner,pins = "PL2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
&r_rsb {
status = "okay";
diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index ceb6ef15d669..7e036b2be762 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -105,6 +105,14 @@
enable-active-high;
gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
};
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&ac100_rtc 1>;
+ clock-names = "ext_clock";
+ /* enables internal regulator and de-asserts reset */
+ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
+ };
};
&ehci0 {
@@ -130,6 +138,21 @@
status = "okay";
};
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>, <&wifi_en_pin_optimus>;
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_cldo3>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&mmc1_pins {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
&mmc2 {
pinctrl-names = "default";
pinctrl-0 = <&mmc2_8bit_pins>;
@@ -199,6 +222,13 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ wifi_en_pin_optimus: wifi_en_pin@0 {
+ allwinner,pins = "PL2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
&r_rsb {
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 3c5214cbe4e6..979ad1aacfb1 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -678,7 +678,8 @@
<GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 5>;
+ clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
@@ -700,6 +701,14 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ mmc1_pins: mmc1 {
+ allwinner,pins = "PG0", "PG1" ,"PG2", "PG3",
+ "PG4", "PG5";
+ allwinner,function = "mmc1";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
mmc2_8bit_pins: mmc2_8bit {
allwinner,pins = "PC6", "PC7", "PC8", "PC9",
"PC10", "PC11", "PC12",
@@ -894,7 +903,8 @@
reg = <0x08002c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apbs_gates 0>;
+ clocks = <&apbs_gates 0>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
resets = <&apbs_rst 0>;
gpio-controller;
interrupt-controller;
diff --git a/arch/arm/boot/dts/tegra124-apalis.dtsi b/arch/arm/boot/dts/tegra124-apalis.dtsi
index e7a73db17613..0819721dda59 100644
--- a/arch/arm/boot/dts/tegra124-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra124-apalis.dtsi
@@ -1595,7 +1595,7 @@
clock-frequency = <400000>;
/* SGTL5000 audio codec */
- sgtl5000: codec@0a {
+ sgtl5000: codec@a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
VDDA-supply = <&reg_3v3>;
diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi b/arch/arm/boot/dts/tegra124-nyan.dtsi
index 271505e0715f..eabfa655a3cd 100644
--- a/arch/arm/boot/dts/tegra124-nyan.dtsi
+++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
@@ -42,6 +42,12 @@
};
};
+ gpu@0,57000000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_gpu>;
+ };
+
serial@70006000 {
/* Debug connector on the bottom of the board near SD card. */
status = "okay";
@@ -214,7 +220,7 @@
regulator-always-on;
};
- sd6 {
+ vdd_gpu: sd6 {
regulator-name = "+VDD_GPU_AP";
regulator-min-microvolt = <650000>;
regulator-max-microvolt = <1200000>;
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 2207c08e3fa3..e8807503f87c 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -376,6 +376,19 @@
status = "disabled";
};
+ gmi@70009000 {
+ compatible = "nvidia,tegra20-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0xd0000000 0xfffffff>;
+ clocks = <&tegra_car TEGRA20_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ status = "disabled";
+ };
+
pwm: pwm@7000a000 {
compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index 192b95177aac..f6c7c3e958ac 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -48,6 +48,24 @@
pinctrl-0 = <&state_default>;
state_default: pinmux {
+ /* Analogue Audio (On-module) */
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0",
+ "dap3_sclk_pp3",
+ "dap3_din_pp1",
+ "dap3_dout_pp2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
/* Apalis BKL1_ON */
pv2 {
nvidia,pins = "pv2";
@@ -429,6 +447,15 @@
status = "okay";
clock-frequency = <100000>;
+ /* SGTL5000 audio codec */
+ sgtl5000: codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&sys_3v3_reg>;
+ VDDIO-supply = <&sys_3v3_reg>;
+ clocks = <&tegra_car TEGRA30_CLK_EXTERN1>;
+ };
+
pmic: tps65911@2d {
compatible = "ti,tps65911";
reg = <0x2d>;
@@ -660,6 +687,12 @@
nvidia,sys-clock-req-active-high;
};
+ ahub@70080000 {
+ i2s@70080500 {
+ status = "okay";
+ };
+ };
+
/* eMMC */
sdhci@78000600 {
status = "okay";
@@ -733,4 +766,20 @@
regulator-always-on;
};
};
+
+ sound {
+ compatible = "toradex,tegra-audio-sgtl5000-apalis_t30",
+ "nvidia,tegra-audio-sgtl5000";
+ nvidia,model = "Toradex Apalis T30";
+ nvidia,audio-routing =
+ "Headphone Jack", "HP_OUT",
+ "LINE_IN", "Line In Jack",
+ "MIC_IN", "Mic Jack";
+ nvidia,i2s-controller = <&tegra_i2s2>;
+ nvidia,audio-codec = <&sgtl5000>;
+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA30_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
};
diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index a265534cd314..5360d638eedc 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -29,6 +29,24 @@
pinctrl-0 = <&state_default>;
state_default: pinmux {
+ /* Analogue Audio (On-module) */
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0",
+ "dap3_sclk_pp3",
+ "dap3_din_pp1",
+ "dap3_dout_pp2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
/* Colibri BL_ON */
pv2 {
nvidia,pins = "pv2";
@@ -207,6 +225,15 @@
status = "okay";
clock-frequency = <100000>;
+ /* SGTL5000 audio codec */
+ sgtl5000: codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&sys_3v3_reg>;
+ VDDIO-supply = <&sys_3v3_reg>;
+ clocks = <&tegra_car TEGRA30_CLK_EXTERN1>;
+ };
+
pmic: tps65911@2d {
compatible = "ti,tps65911";
reg = <0x2d>;
@@ -396,6 +423,12 @@
nvidia,sys-clock-req-active-high;
};
+ ahub@70080000 {
+ i2s@70080500 {
+ status = "okay";
+ };
+ };
+
/* eMMC */
sdhci@78000600 {
status = "okay";
@@ -471,4 +504,20 @@
regulator-always-on;
};
};
+
+ sound {
+ compatible = "toradex,tegra-audio-sgtl5000-colibri_t30",
+ "nvidia,tegra-audio-sgtl5000";
+ nvidia,model = "Toradex Colibri T30";
+ nvidia,audio-routing =
+ "Headphone Jack", "HP_OUT",
+ "LINE_IN", "Line In Jack",
+ "MIC_IN", "Mic Jack";
+ nvidia,i2s-controller = <&tegra_i2s2>;
+ nvidia,audio-codec = <&sgtl5000>;
+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA30_CLK_EXTERN1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+ };
};
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 5030065cbdfe..bbb1c002e7f1 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -439,6 +439,19 @@
status = "disabled";
};
+ gmi@70009000 {
+ compatible = "nvidia,tegra30-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x48000000 0x7ffffff>;
+ clocks = <&tegra_car TEGRA30_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ status = "disabled";
+ };
+
pwm: pwm@7000a000 {
compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
diff --git a/arch/arm/boot/dts/tps65217.dtsi b/arch/arm/boot/dts/tps65217.dtsi
index a63272422d76..02de56b55823 100644
--- a/arch/arm/boot/dts/tps65217.dtsi
+++ b/arch/arm/boot/dts/tps65217.dtsi
@@ -13,6 +13,18 @@
&tps {
compatible = "ti,tps65217";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ charger {
+ compatible = "ti,tps65217-charger";
+ status = "disabled";
+ };
+
+ pwrbutton {
+ compatible = "ti,tps65217-pwrbutton";
+ status = "disabled";
+ };
regulators {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/uniphier-common32.dtsi b/arch/arm/boot/dts/uniphier-common32.dtsi
deleted file mode 100644
index 8c8a85176b64..000000000000
--- a/arch/arm/boot/dts/uniphier-common32.dtsi
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Device Tree Source commonly used by UniPhier ARM SoCs
- *
- * Copyright (C) 2015-2016 Socionext Inc.
- * Author: 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"
-
-/ {
- psci {
- compatible = "arm,psci-0.2";
- method = "smc";
- };
-
- clocks {
- refclk: ref {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- };
- };
-
- soc: soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- interrupt-parent = <&intc>;
-
- serial0: serial@54006800 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006800 0x40>;
- interrupts = <0 33 4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- clocks = <&peri_clk 0>;
- };
-
- serial1: serial@54006900 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006900 0x40>;
- interrupts = <0 35 4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- clocks = <&peri_clk 1>;
- };
-
- serial2: serial@54006a00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006a00 0x40>;
- interrupts = <0 37 4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- clocks = <&peri_clk 2>;
- };
-
- serial3: serial@54006b00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006b00 0x40>;
- interrupts = <0 177 4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- clocks = <&peri_clk 3>;
- };
-
- system_bus: system-bus@58c00000 {
- compatible = "socionext,uniphier-system-bus";
- status = "disabled";
- reg = <0x58c00000 0x400>;
- #address-cells = <2>;
- #size-cells = <1>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_system_bus>;
- };
-
- smpctrl@59800000 {
- compatible = "socionext,uniphier-smpctrl";
- reg = <0x59801000 0x400>;
- };
-
- mioctrl@59810000 {
- compatible = "socionext,uniphier-mioctrl",
- "simple-mfd", "syscon";
- reg = <0x59810000 0x800>;
-
- mio_clk: clock {
- #clock-cells = <1>;
- };
-
- mio_rst: reset {
- #reset-cells = <1>;
- };
- };
-
- perictrl@59820000 {
- compatible = "socionext,uniphier-perictrl",
- "simple-mfd", "syscon";
- reg = <0x59820000 0x200>;
-
- peri_clk: clock {
- #clock-cells = <1>;
- };
-
- peri_rst: reset {
- #reset-cells = <1>;
- };
- };
-
- 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;
- };
-
- soc-glue@5f800000 {
- compatible = "socionext,uniphier-soc-glue",
- "simple-mfd", "syscon";
- reg = <0x5f800000 0x2000>;
-
- pinctrl: pinctrl {
- /* specify compatible in each SoC DTSI */
- };
- };
-
- sysctrl@61840000 {
- compatible = "socionext,uniphier-sysctrl",
- "simple-mfd", "syscon";
- reg = <0x61840000 0x4000>;
-
- sys_clk: clock {
- #clock-cells = <1>;
- };
-
- sys_rst: reset {
- #reset-cells = <1>;
- };
- };
- };
-};
-
-/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-ld4.dtsi b/arch/arm/boot/dts/uniphier-ld4.dtsi
index 95f342c9d9c1..a7c494d7c43a 100644
--- a/arch/arm/boot/dts/uniphier-ld4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ld4.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "uniphier-common32.dtsi"
+/include/ "skeleton.dtsi"
/ {
compatible = "socionext,uniphier-ld4";
@@ -61,147 +61,267 @@
};
};
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
clocks {
+ refclk: ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
arm_timer_clk: arm_timer_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
};
};
-};
-
-&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>;
- };
- i2c0: i2c@58400000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58400000 0x40>;
+ soc {
+ compatible = "simple-bus";
#address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 41 1>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- clocks = <&peri_clk 4>;
- clock-frequency = <100000>;
- };
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&intc>;
- 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 = <&peri_clk 5>;
- clock-frequency = <100000>;
- };
+ 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>;
+ };
- /* 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 = <&peri_clk 6>;
- clock-frequency = <400000>;
- };
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&peri_clk 0>;
+ };
- 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 = <&peri_clk 7>;
- clock-frequency = <100000>;
- };
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&peri_clk 1>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
- resets = <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>, <&sys_rst 8>;
- };
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&peri_clk 2>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
- resets = <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>, <&sys_rst 8>;
- };
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 29 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&peri_clk 3>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
- resets = <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>, <&sys_rst 8>;
- };
+ 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 = <&peri_clk 4>;
+ clock-frequency = <100000>;
+ };
-};
+ 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 = <&peri_clk 5>;
+ clock-frequency = <100000>;
+ };
-&refclk {
- clock-frequency = <24576000>;
-};
+ /* 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 = <&peri_clk 6>;
+ clock-frequency = <400000>;
+ };
-&serial3 {
- interrupts = <0 29 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 = <&peri_clk 7>;
+ clock-frequency = <100000>;
+ };
-&mio_clk {
- compatible = "socionext,uniphier-ld4-mio-clock";
-};
+ system_bus: system-bus@58c00000 {
+ compatible = "socionext,uniphier-system-bus";
+ status = "disabled";
+ reg = <0x58c00000 0x400>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
+ };
-&mio_rst {
- compatible = "socionext,uniphier-ld4-mio-reset";
- resets = <&sys_rst 7>;
-};
+ smpctrl@59800000 {
+ compatible = "socionext,uniphier-smpctrl";
+ reg = <0x59801000 0x400>;
+ };
-&peri_clk {
- compatible = "socionext,uniphier-ld4-peri-clock";
-};
+ mioctrl@59810000 {
+ compatible = "socionext,uniphier-ld4-mioctrl",
+ "simple-mfd", "syscon";
+ reg = <0x59810000 0x800>;
-&peri_rst {
- compatible = "socionext,uniphier-ld4-peri-reset";
-};
+ mio_clk: clock {
+ compatible = "socionext,uniphier-ld4-mio-clock";
+ #clock-cells = <1>;
+ };
-&pinctrl {
- compatible = "socionext,uniphier-ld4-pinctrl";
-};
+ mio_rst: reset {
+ compatible = "socionext,uniphier-ld4-mio-reset";
+ #reset-cells = <1>;
+ };
+ };
-&sys_clk {
- compatible = "socionext,uniphier-ld4-clock";
-};
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-ld4-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-ld4-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-ld4-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
+ <&mio_rst 12>;
+ };
+
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
+ <&mio_rst 13>;
+ };
-&sys_rst {
- compatible = "socionext,uniphier-ld4-reset";
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
+ <&mio_rst 14>;
+ };
+
+ soc-glue@5f800000 {
+ compatible = "socionext,uniphier-ld4-soc-glue",
+ "simple-mfd", "syscon";
+ reg = <0x5f800000 0x2000>;
+
+ pinctrl: pinctrl {
+ compatible = "socionext,uniphier-ld4-pinctrl";
+ };
+ };
+
+ 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;
+ };
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-ld4-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x10000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-ld4-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-ld4-reset";
+ #reset-cells = <1>;
+ };
+ };
+ };
};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-pro4.dtsi b/arch/arm/boot/dts/uniphier-pro4.dtsi
index ba700267ad66..e960b09ff01c 100644
--- a/arch/arm/boot/dts/uniphier-pro4.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro4.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "uniphier-common32.dtsi"
+/include/ "skeleton.dtsi"
/ {
compatible = "socionext,uniphier-pro4";
@@ -69,155 +69,279 @@
};
};
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
clocks {
+ refclk: ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
arm_timer_clk: arm_timer_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
};
};
-};
-&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>;
- };
-
- i2c0: i2c@58780000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58780000 0x80>;
+ soc {
+ compatible = "simple-bus";
#address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 41 4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- clocks = <&peri_clk 4>;
- clock-frequency = <100000>;
- };
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&intc>;
- 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 = <&peri_clk 5>;
- clock-frequency = <100000>;
- };
+ 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>;
+ };
- 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 = <&peri_clk 6>;
- clock-frequency = <100000>;
- };
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&peri_clk 0>;
+ };
- 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 = <&peri_clk 7>;
- clock-frequency = <100000>;
- };
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&peri_clk 1>;
+ };
- /* i2c4 does not exist */
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&peri_clk 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 = <&peri_clk 9>;
- clock-frequency = <400000>;
- };
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 177 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&peri_clk 3>;
+ };
- /* 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 = <&peri_clk 10>;
- 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 = <&peri_clk 4>;
+ clock-frequency = <100000>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
- resets = <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>, <&sys_rst 8>;
- };
+ 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 = <&peri_clk 5>;
+ clock-frequency = <100000>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
- resets = <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>, <&sys_rst 8>;
- };
-};
+ 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 = <&peri_clk 6>;
+ clock-frequency = <100000>;
+ };
-&refclk {
- clock-frequency = <25000000>;
-};
+ 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 = <&peri_clk 7>;
+ clock-frequency = <100000>;
+ };
-&mio_clk {
- compatible = "socionext,uniphier-pro4-mio-clock";
-};
+ /* i2c4 does not exist */
-&mio_rst {
- compatible = "socionext,uniphier-pro4-mio-reset";
- resets = <&sys_rst 7>;
-};
+ /* 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 = <&peri_clk 9>;
+ clock-frequency = <400000>;
+ };
-&peri_clk {
- compatible = "socionext,uniphier-pro4-peri-clock";
-};
+ /* 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 = <&peri_clk 10>;
+ clock-frequency = <400000>;
+ };
-&peri_rst {
- compatible = "socionext,uniphier-pro4-peri-reset";
-};
+ system_bus: system-bus@58c00000 {
+ compatible = "socionext,uniphier-system-bus";
+ status = "disabled";
+ reg = <0x58c00000 0x400>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
+ };
-&pinctrl {
- compatible = "socionext,uniphier-pro4-pinctrl";
-};
+ smpctrl@59800000 {
+ compatible = "socionext,uniphier-smpctrl";
+ reg = <0x59801000 0x400>;
+ };
-&sys_clk {
- compatible = "socionext,uniphier-pro4-clock";
-};
+ mioctrl@59810000 {
+ compatible = "socionext,uniphier-pro4-mioctrl",
+ "simple-mfd", "syscon";
+ reg = <0x59810000 0x800>;
+
+ mio_clk: clock {
+ compatible = "socionext,uniphier-pro4-mio-clock";
+ #clock-cells = <1>;
+ };
+
+ mio_rst: reset {
+ compatible = "socionext,uniphier-pro4-mio-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-pro4-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-pro4-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-pro4-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
-&sys_rst {
- compatible = "socionext,uniphier-pro4-reset";
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
+ <&mio_rst 12>;
+ };
+
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
+ <&mio_rst 13>;
+ };
+
+ soc-glue@5f800000 {
+ compatible = "socionext,uniphier-pro4-soc-glue",
+ "simple-mfd", "syscon";
+ reg = <0x5f800000 0x2000>;
+
+ pinctrl: pinctrl {
+ compatible = "socionext,uniphier-pro4-pinctrl";
+ };
+ };
+
+ timer@60000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x60000200 0x20>;
+ interrupts = <1 11 0x304>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ timer@60000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x60000600 0x20>;
+ interrupts = <1 13 0x304>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ intc: interrupt-controller@60001000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x60001000 0x1000>,
+ <0x60000100 0x100>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ };
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-pro4-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x10000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-pro4-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-pro4-reset";
+ #reset-cells = <1>;
+ };
+ };
+ };
};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi b/arch/arm/boot/dts/uniphier-pro5.dtsi
index 5357ea9c14b1..dbc5e5333163 100644
--- a/arch/arm/boot/dts/uniphier-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro5.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "uniphier-common32.dtsi"
+/include/ "skeleton.dtsi"
/ {
compatible = "socionext,uniphier-pro5";
@@ -56,157 +56,355 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ clocks = <&sys_clk 32>;
enable-method = "psci";
next-level-cache = <&l2>;
+ operating-points-v2 = <&cpu_opp>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
+ clocks = <&sys_clk 32>;
enable-method = "psci";
next-level-cache = <&l2>;
+ operating-points-v2 = <&cpu_opp>;
};
};
+ cpu_opp: opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@116667000 {
+ opp-hz = /bits/ 64 <116667000>;
+ clock-latency-ns = <300>;
+ };
+ opp@150000000 {
+ opp-hz = /bits/ 64 <150000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@175000000 {
+ opp-hz = /bits/ 64 <175000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@233334000 {
+ opp-hz = /bits/ 64 <233334000>;
+ clock-latency-ns = <300>;
+ };
+ opp@300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@350000000 {
+ opp-hz = /bits/ 64 <350000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@466667000 {
+ opp-hz = /bits/ 64 <466667000>;
+ clock-latency-ns = <300>;
+ };
+ opp@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@933334000 {
+ opp-hz = /bits/ 64 <933334000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ clock-latency-ns = <300>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
clocks {
+ refclk: ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ };
+
arm_timer_clk: arm_timer_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
};
};
-};
-&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>;
- };
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&intc>;
- 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>;
- };
+ 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>;
+ };
- 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 = <&peri_clk 4>;
- clock-frequency = <100000>;
- };
+ 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>;
+ };
- 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 = <&peri_clk 5>;
- clock-frequency = <100000>;
- };
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&peri_clk 0>;
+ };
- 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 = <&peri_clk 6>;
- clock-frequency = <100000>;
- };
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&peri_clk 1>;
+ };
- 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 = <&peri_clk 7>;
- clock-frequency = <100000>;
- };
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&peri_clk 2>;
+ };
- /* i2c4 does not exist */
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 177 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&peri_clk 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 = <&peri_clk 9>;
- 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 = <&peri_clk 4>;
+ 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 = <&peri_clk 10>;
- 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 = <&peri_clk 5>;
+ clock-frequency = <100000>;
+ };
-&refclk {
- clock-frequency = <20000000>;
-};
+ 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 = <&peri_clk 6>;
+ clock-frequency = <100000>;
+ };
-&mio_clk {
- compatible = "socionext,uniphier-pro5-sd-clock";
-};
+ 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 = <&peri_clk 7>;
+ clock-frequency = <100000>;
+ };
-&mio_rst {
- compatible = "socionext,uniphier-pro5-sd-reset";
-};
+ /* i2c4 does not exist */
-&peri_clk {
- compatible = "socionext,uniphier-pro5-peri-clock";
-};
+ /* 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 = <&peri_clk 9>;
+ clock-frequency = <400000>;
+ };
-&peri_rst {
- compatible = "socionext,uniphier-pro5-peri-reset";
-};
+ /* 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 = <&peri_clk 10>;
+ clock-frequency = <400000>;
+ };
-&pinctrl {
- compatible = "socionext,uniphier-pro5-pinctrl";
-};
+ system_bus: system-bus@58c00000 {
+ compatible = "socionext,uniphier-system-bus";
+ status = "disabled";
+ reg = <0x58c00000 0x400>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
+ };
-&sys_clk {
- compatible = "socionext,uniphier-pro5-clock";
-};
+ smpctrl@59800000 {
+ compatible = "socionext,uniphier-smpctrl";
+ reg = <0x59801000 0x400>;
+ };
-&sys_rst {
- compatible = "socionext,uniphier-pro5-reset";
+ sdctrl@59810000 {
+ compatible = "socionext,uniphier-pro5-sdctrl",
+ "simple-mfd", "syscon";
+ reg = <0x59810000 0x800>;
+
+ sd_clk: clock {
+ compatible = "socionext,uniphier-pro5-sd-clock";
+ #clock-cells = <1>;
+ };
+
+ sd_rst: reset {
+ compatible = "socionext,uniphier-pro5-sd-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-pro5-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-pro5-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-pro5-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ soc-glue@5f800000 {
+ compatible = "socionext,uniphier-pro5-soc-glue",
+ "simple-mfd", "syscon";
+ reg = <0x5f800000 0x2000>;
+
+ pinctrl: pinctrl {
+ compatible = "socionext,uniphier-pro5-pinctrl";
+ };
+ };
+
+ timer@60000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x60000200 0x20>;
+ interrupts = <1 11 0x304>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ timer@60000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x60000600 0x20>;
+ interrupts = <1 13 0x304>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ intc: interrupt-controller@60001000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x60001000 0x1000>,
+ <0x60000100 0x100>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ };
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-pro5-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x10000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-pro5-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-pro5-reset";
+ #reset-cells = <1>;
+ };
+ };
+ };
};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-pxs2.dtsi b/arch/arm/boot/dts/uniphier-pxs2.dtsi
index 950f07ba0337..e9e031d63c1a 100644
--- a/arch/arm/boot/dts/uniphier-pxs2.dtsi
+++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "uniphier-common32.dtsi"
+/include/ "skeleton.dtsi"
/ {
compatible = "socionext,uniphier-pxs2";
@@ -56,170 +56,339 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ clocks = <&sys_clk 32>;
enable-method = "psci";
next-level-cache = <&l2>;
+ operating-points-v2 = <&cpu_opp>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
+ clocks = <&sys_clk 32>;
enable-method = "psci";
next-level-cache = <&l2>;
+ operating-points-v2 = <&cpu_opp>;
};
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <2>;
+ clocks = <&sys_clk 32>;
enable-method = "psci";
next-level-cache = <&l2>;
+ operating-points-v2 = <&cpu_opp>;
};
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <3>;
+ clocks = <&sys_clk 32>;
enable-method = "psci";
next-level-cache = <&l2>;
+ operating-points-v2 = <&cpu_opp>;
};
};
+ cpu_opp: opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@150000000 {
+ opp-hz = /bits/ 64 <150000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ clock-latency-ns = <300>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
clocks {
+ refclk: ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
arm_timer_clk: arm_timer_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
};
};
-};
-
-&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>;
- };
- i2c0: i2c@58780000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58780000 0x80>;
+ soc {
+ compatible = "simple-bus";
#address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 41 4>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- clocks = <&peri_clk 4>;
- clock-frequency = <100000>;
- };
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&intc>;
- 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 = <&peri_clk 5>;
- clock-frequency = <100000>;
- };
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
+ <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>;
+ };
- 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 = <&peri_clk 6>;
- clock-frequency = <100000>;
- };
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&peri_clk 0>;
+ };
- 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 = <&peri_clk 7>;
- clock-frequency = <100000>;
- };
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&peri_clk 1>;
+ };
- /* 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 = <&peri_clk 8>;
- clock-frequency = <400000>;
- };
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&peri_clk 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 = <&peri_clk 9>;
- clock-frequency = <400000>;
- };
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 177 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&peri_clk 3>;
+ };
- /* 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 = <&peri_clk 10>;
- 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 = <&peri_clk 4>;
+ clock-frequency = <100000>;
+ };
-&refclk {
- clock-frequency = <25000000>;
-};
+ 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 = <&peri_clk 5>;
+ clock-frequency = <100000>;
+ };
-&mio_clk {
- compatible = "socionext,uniphier-pxs2-sd-clock";
-};
+ 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 = <&peri_clk 6>;
+ clock-frequency = <100000>;
+ };
-&mio_rst {
- compatible = "socionext,uniphier-pxs2-sd-reset";
-};
+ 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 = <&peri_clk 7>;
+ clock-frequency = <100000>;
+ };
-&peri_clk {
- compatible = "socionext,uniphier-pxs2-peri-clock";
-};
+ /* 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 = <&peri_clk 8>;
+ clock-frequency = <400000>;
+ };
-&peri_rst {
- compatible = "socionext,uniphier-pxs2-peri-reset";
-};
+ /* 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 = <&peri_clk 9>;
+ clock-frequency = <400000>;
+ };
-&pinctrl {
- compatible = "socionext,uniphier-pxs2-pinctrl";
-};
+ /* 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 = <&peri_clk 10>;
+ clock-frequency = <400000>;
+ };
-&sys_clk {
- compatible = "socionext,uniphier-pxs2-clock";
-};
+ system_bus: system-bus@58c00000 {
+ compatible = "socionext,uniphier-system-bus";
+ status = "disabled";
+ reg = <0x58c00000 0x400>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
+ };
+
+ smpctrl@59800000 {
+ compatible = "socionext,uniphier-smpctrl";
+ reg = <0x59801000 0x400>;
+ };
+
+ sdctrl@59810000 {
+ compatible = "socionext,uniphier-pxs2-sdctrl",
+ "simple-mfd", "syscon";
+ reg = <0x59810000 0x800>;
-&sys_rst {
- compatible = "socionext,uniphier-pxs2-reset";
+ sd_clk: clock {
+ compatible = "socionext,uniphier-pxs2-sd-clock";
+ #clock-cells = <1>;
+ };
+
+ sd_rst: reset {
+ compatible = "socionext,uniphier-pxs2-sd-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-pxs2-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-pxs2-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-pxs2-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ soc-glue@5f800000 {
+ compatible = "socionext,uniphier-pxs2-soc-glue",
+ "simple-mfd", "syscon";
+ reg = <0x5f800000 0x2000>;
+
+ pinctrl: pinctrl {
+ compatible = "socionext,uniphier-pxs2-pinctrl";
+ };
+ };
+
+ timer@60000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x60000200 0x20>;
+ interrupts = <1 11 0xf04>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ timer@60000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x60000600 0x20>;
+ interrupts = <1 13 0xf04>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ intc: interrupt-controller@60001000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x60001000 0x1000>,
+ <0x60000100 0x100>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ };
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-pxs2-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x10000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-pxs2-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-pxs2-reset";
+ #reset-cells = <1>;
+ };
+ };
+ };
};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-sld3.dtsi b/arch/arm/boot/dts/uniphier-sld3.dtsi
index 5fa96c939b5c..9fad6bd2db8a 100644
--- a/arch/arm/boot/dts/uniphier-sld3.dtsi
+++ b/arch/arm/boot/dts/uniphier-sld3.dtsi
@@ -135,7 +135,6 @@
reg = <0x54006800 0x40>;
interrupts = <0 33 4>;
clocks = <&sys_clk 0>;
- fifo-size = <64>;
};
serial1: serial@54006900 {
@@ -144,7 +143,6 @@
reg = <0x54006900 0x40>;
interrupts = <0 35 4>;
clocks = <&sys_clk 0>;
- fifo-size = <64>;
};
serial2: serial@54006a00 {
@@ -153,7 +151,6 @@
reg = <0x54006a00 0x40>;
interrupts = <0 37 4>;
clocks = <&sys_clk 0>;
- fifo-size = <64>;
};
i2c0: i2c@58400000 {
@@ -225,7 +222,7 @@
};
mioctrl@59810000 {
- compatible = "socionext,uniphier-mioctrl",
+ compatible = "socionext,uniphier-sld3-mioctrl",
"simple-mfd", "syscon";
reg = <0x59810000 0x800>;
@@ -245,6 +242,9 @@
status = "disabled";
reg = <0x5a800100 0x100>;
interrupts = <0 80 4>;
+ clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
+ <&mio_rst 12>;
};
usb1: usb@5a810100 {
@@ -252,6 +252,9 @@
status = "disabled";
reg = <0x5a810100 0x100>;
interrupts = <0 81 4>;
+ clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
+ <&mio_rst 13>;
};
usb2: usb@5a820100 {
@@ -259,6 +262,9 @@
status = "disabled";
reg = <0x5a820100 0x100>;
interrupts = <0 82 4>;
+ clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
+ <&mio_rst 14>;
};
usb3: usb@5a830100 {
@@ -266,12 +272,15 @@
status = "disabled";
reg = <0x5a830100 0x100>;
interrupts = <0 83 4>;
+ clocks = <&mio_clk 7>, <&mio_clk 11>, <&mio_clk 15>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 11>,
+ <&mio_rst 15>;
};
sysctrl@f1840000 {
- compatible = "socionext,uniphier-sysctrl",
+ compatible = "socionext,uniphier-sld3-sysctrl",
"simple-mfd", "syscon";
- reg = <0xf1840000 0x4000>;
+ reg = <0xf1840000 0x10000>;
sys_clk: clock {
compatible = "socionext,uniphier-sld3-clock";
diff --git a/arch/arm/boot/dts/uniphier-sld8.dtsi b/arch/arm/boot/dts/uniphier-sld8.dtsi
index d8cf0e7e11ea..b2c980ead7f0 100644
--- a/arch/arm/boot/dts/uniphier-sld8.dtsi
+++ b/arch/arm/boot/dts/uniphier-sld8.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "uniphier-common32.dtsi"
+/include/ "skeleton.dtsi"
/ {
compatible = "socionext,uniphier-sld8";
@@ -61,146 +61,267 @@
};
};
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
clocks {
+ refclk: ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
arm_timer_clk: arm_timer_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
};
};
-};
-
-&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>;
- };
- i2c0: i2c@58400000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58400000 0x40>;
+ soc {
+ compatible = "simple-bus";
#address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 41 1>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- clocks = <&peri_clk 4>;
- clock-frequency = <100000>;
- };
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&intc>;
- 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 = <&peri_clk 5>;
- clock-frequency = <100000>;
- };
+ 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>;
+ };
- /* 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 = <&peri_clk 6>;
- clock-frequency = <400000>;
- };
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&peri_clk 0>;
+ };
- 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 = <&peri_clk 7>;
- clock-frequency = <100000>;
- };
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&peri_clk 1>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
- resets = <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>, <&sys_rst 8>;
- };
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&peri_clk 2>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
- resets = <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>, <&sys_rst 8>;
- };
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 29 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&peri_clk 3>;
+ };
- 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>;
- clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
- resets = <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>, <&sys_rst 8>;
- };
-};
+ 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 = <&peri_clk 4>;
+ clock-frequency = <100000>;
+ };
-&refclk {
- clock-frequency = <25000000>;
-};
+ 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 = <&peri_clk 5>;
+ clock-frequency = <100000>;
+ };
-&serial3 {
- interrupts = <0 29 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 = <&peri_clk 6>;
+ clock-frequency = <400000>;
+ };
-&mio_clk {
- compatible = "socionext,uniphier-sld8-mio-clock";
-};
+ 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 = <&peri_clk 7>;
+ clock-frequency = <100000>;
+ };
-&mio_rst {
- compatible = "socionext,uniphier-sld8-mio-reset";
- resets = <&sys_rst 7>;
-};
+ system_bus: system-bus@58c00000 {
+ compatible = "socionext,uniphier-system-bus";
+ status = "disabled";
+ reg = <0x58c00000 0x400>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
+ };
-&peri_clk {
- compatible = "socionext,uniphier-sld8-peri-clock";
-};
+ smpctrl@59800000 {
+ compatible = "socionext,uniphier-smpctrl";
+ reg = <0x59801000 0x400>;
+ };
-&peri_rst {
- compatible = "socionext,uniphier-sld8-peri-reset";
-};
+ mioctrl@59810000 {
+ compatible = "socionext,uniphier-sld8-mioctrl",
+ "simple-mfd", "syscon";
+ reg = <0x59810000 0x800>;
-&pinctrl {
- compatible = "socionext,uniphier-sld8-pinctrl";
-};
+ mio_clk: clock {
+ compatible = "socionext,uniphier-sld8-mio-clock";
+ #clock-cells = <1>;
+ };
-&sys_clk {
- compatible = "socionext,uniphier-sld8-clock";
-};
+ mio_rst: reset {
+ compatible = "socionext,uniphier-sld8-mio-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-sld8-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-sld8-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-sld8-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
+ <&mio_rst 12>;
+ };
+
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
+ <&mio_rst 13>;
+ };
+
+ 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>;
+ clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
+ resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
+ <&mio_rst 14>;
+ };
-&sys_rst {
- compatible = "socionext,uniphier-sld8-reset";
+ soc-glue@5f800000 {
+ compatible = "socionext,uniphier-sld8-soc-glue",
+ "simple-mfd", "syscon";
+ reg = <0x5f800000 0x2000>;
+
+ pinctrl: pinctrl {
+ compatible = "socionext,uniphier-sld8-pinctrl";
+ };
+ };
+
+ 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;
+ };
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-sld8-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x10000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-sld8-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-sld8-reset";
+ #reset-cells = <1>;
+ };
+ };
+ };
};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 0205c97efdef..45d08cc37b01 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -39,6 +39,7 @@
reg = <0>;
cci-control-port = <&cci_control1>;
cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
+ capacity-dmips-mhz = <1024>;
};
cpu1: cpu@1 {
@@ -47,6 +48,7 @@
reg = <1>;
cci-control-port = <&cci_control1>;
cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
+ capacity-dmips-mhz = <1024>;
};
cpu2: cpu@2 {
@@ -55,6 +57,7 @@
reg = <0x100>;
cci-control-port = <&cci_control2>;
cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+ capacity-dmips-mhz = <516>;
};
cpu3: cpu@3 {
@@ -63,6 +66,7 @@
reg = <0x101>;
cci-control-port = <&cci_control2>;
cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+ capacity-dmips-mhz = <516>;
};
cpu4: cpu@4 {
@@ -71,6 +75,7 @@
reg = <0x102>;
cci-control-port = <&cci_control2>;
cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
+ capacity-dmips-mhz = <516>;
};
idle-states {
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index b7417094dc11..21bfef957b68 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -108,6 +108,10 @@
status = "okay";
};
+&edma1 {
+ status = "okay";
+};
+
&esdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc1>;
diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 1552db00cc59..7ea617e47fe4 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -538,13 +538,6 @@
};
};
-&i2c3 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- status = "okay";
-};
-
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0>;
@@ -714,13 +707,6 @@
>;
};
- pinctrl_i2c3: i2c3grp {
- fsl,pins = <
- VF610_PAD_PTA30__I2C3_SCL 0x37ff
- VF610_PAD_PTA31__I2C3_SDA 0x37ff
- >;
- };
-
pinctrl_leds_debug: pinctrl-leds-debug {
fsl,pins = <
VF610_PAD_PTD20__GPIO_74 0x31c2
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2c13ec696ac5..e9d28474c26a 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -194,6 +194,9 @@
clocks = <&clks VF610_CLK_DSPI0>;
clock-names = "dspi";
spi-num-chipselects = <6>;
+ dmas = <&edma1 1 12>,
+ <&edma1 1 13>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -206,6 +209,9 @@
clocks = <&clks VF610_CLK_DSPI1>;
clock-names = "dspi";
spi-num-chipselects = <4>;
+ dmas = <&edma1 1 14>,
+ <&edma1 1 15>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -520,6 +526,12 @@
status = "disabled";
};
+ ocotp: ocotp@400a5000 {
+ compatible = "fsl,vf610-ocotp";
+ reg = <0x400a5000 0x1000>;
+ clocks = <&clks VF610_CLK_OCOTP>;
+ };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x400a7000 0x2000>;
@@ -561,6 +573,9 @@
clocks = <&clks VF610_CLK_DSPI2>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+ dmas = <&edma1 0 10>,
+ <&edma1 0 11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -573,6 +588,9 @@
clocks = <&clks VF610_CLK_DSPI3>;
clock-names = "dspi";
spi-num-chipselects = <2>;
+ dmas = <&edma1 0 12>,
+ <&edma1 0 13>;
+ dma-names = "rx", "tx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index f283ff08381c..f3ac9bfe580e 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -10,9 +10,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-/include/ "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
compatible = "xlnx,zynq-7000";
cpus {
@@ -41,14 +42,15 @@
};
};
- pmu {
+ pmu@f8891000 {
compatible = "arm,cortex-a9-pmu";
interrupts = <0 5 4>, <0 6 4>;
interrupt-parent = <&intc>;
- reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
+ reg = <0xf8891000 0x1000>,
+ <0xf8893000 0x1000>;
};
- regulator_vccpint: fixedregulator@0 {
+ regulator_vccpint: fixedregulator {
compatible = "regulator-fixed";
regulator-name = "VCCPINT";
regulator-min-microvolt = <1000000>;
diff --git a/arch/arm/boot/dts/zynq-microzed.dts b/arch/arm/boot/dts/zynq-microzed.dts
new file mode 100644
index 000000000000..b9376a4904b4
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-microzed.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 - 2014 Xilinx
+ * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+ model = "Zynq MicroZED Development Board";
+ compatible = "xlnx,zynq-microzed", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ serial0 = &uart1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "earlycon";
+ stdout-path = "serial0:115200n8";
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy>;
+
+ ethernet_phy: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
+};
+
+&pinctrl0 {
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts
index 307ed201d658..64a6390fc501 100644
--- a/arch/arm/boot/dts/zynq-parallella.dts
+++ b/arch/arm/boot/dts/zynq-parallella.dts
@@ -28,7 +28,7 @@
serial0 = &uart1;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index e96959b2e67a..0cdad2cc8b78 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -24,7 +24,7 @@
serial0 = &uart1;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts
index be6a986bbbd8..ad4bb06dba25 100644
--- a/arch/arm/boot/dts/zynq-zc706.dts
+++ b/arch/arm/boot/dts/zynq-zc706.dts
@@ -24,7 +24,7 @@
serial0 = &uart1;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts
index 7250c1eac7f9..325379f7983c 100644
--- a/arch/arm/boot/dts/zynq-zed.dts
+++ b/arch/arm/boot/dts/zynq-zed.dts
@@ -23,7 +23,7 @@
serial0 = &uart1;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x20000000>;
};
diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts
index d9e0f3e70671..590ec24b8749 100644
--- a/arch/arm/boot/dts/zynq-zybo.dts
+++ b/arch/arm/boot/dts/zynq-zybo.dts
@@ -23,7 +23,7 @@
serial0 = &uart1;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x20000000>;
};
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index f0dea52e49c4..113a5d815060 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -55,8 +55,9 @@ CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PXA2XX=y
CONFIG_BLK_DEV_LOOP=m
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_ATA=m
+CONFIG_PATA_PCMCIA=m
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_SMC91X=m
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index 558ecd8f66ff..ab19ff1a0b71 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -34,7 +34,6 @@ CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_SA1100=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_RAM=y
-CONFIG_IDE=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCMCIA=y
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index d59009878312..2a604aa3195b 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -42,8 +42,6 @@ CONFIG_MTD_SA1100=y
CONFIG_PARPORT=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECD=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 79de828e49ad..4b89f4e6e849 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -73,6 +73,8 @@ CONFIG_SPI_BCM2835=y
CONFIG_SPI_BCM2835AUX=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_BCM2835_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_BCM2835_WDT=y
CONFIG_DRM=y
diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
index dce912d146b4..57a2a18690b1 100644
--- a/arch/arm/configs/cerfcube_defconfig
+++ b/arch/arm/configs/cerfcube_defconfig
@@ -39,7 +39,6 @@ CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_SA1100=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_RAM=m
-CONFIG_IDE=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 52dbad5619e2..a8f3c596c39c 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -43,8 +43,9 @@ CONFIG_MTD_SA1100=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=1024
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index c1470a00f55a..462533bd84c6 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -99,15 +99,14 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_SHARPSL=y
CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_USB_CATC=m
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 5e5dd6bc5ed9..8806754f7175 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -7,13 +7,13 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CGROUPS=y
+CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
@@ -34,6 +34,7 @@ CONFIG_DAVINCI_MUX_WARNINGS=y
CONFIG_DAVINCI_RESET_CLOCKS=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
+CONFIG_SECCOMP=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
@@ -52,10 +53,10 @@ CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NETFILTER=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FW_LOADER is not set
+CONFIG_DA8XX_MSTPRI=y
CONFIG_MTD=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_CFI=m
@@ -116,6 +117,8 @@ CONFIG_SPI_DAVINCI=m
CONFIG_PINCTRL_SINGLE=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_PCA953X=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
CONFIG_WATCHDOG=y
CONFIG_DAVINCI_WATCHDOG=m
CONFIG_MFD_DM355EVM_MSP=y
@@ -123,6 +126,8 @@ CONFIG_TPS6507X=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_TPS6507X=y
+CONFIG_DRM=m
+CONFIG_DRM_TILCDC=m
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DA8XX=y
@@ -153,10 +158,13 @@ CONFIG_HID_SONY=m
CONFIG_HID_SUNPLUS=m
CONFIG_USB=m
CONFIG_USB_MON=m
+CONFIG_USB_OHCI_HCD=m
CONFIG_USB_STORAGE=m
CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_DA8XX=m
CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_TEST=m
+CONFIG_NOP_USB_XCEIV=m
CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -167,28 +175,32 @@ 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=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_DAVINCI=m
+CONFIG_MMC_DAVINCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_GPIO=m
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_OMAP=m
CONFIG_DMADEVICES=y
CONFIG_TI_EDMA=y
CONFIG_MEMORY=y
CONFIG_TI_AEMIF=m
+CONFIG_DA8XX_DDRCTL=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
CONFIG_AUTOFS4_FS=m
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
CONFIG_JFFS2_FS=m
CONFIG_UBIFS_FS=m
CONFIG_CRAMFS=y
diff --git a/arch/arm/configs/dram_0xc0000000.config b/arch/arm/configs/dram_0xc0000000.config
new file mode 100644
index 000000000000..343d5333d973
--- /dev/null
+++ b/arch/arm/configs/dram_0xc0000000.config
@@ -0,0 +1 @@
+CONFIG_DRAM_BASE=0xc0000000
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index c58f6841f8aa..79c415c33f69 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -155,6 +155,7 @@ CONFIG_VIDEO_EXYNOS4_FIMC_IS=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
+CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_DRM=y
CONFIG_DRM_EXYNOS=y
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 0142ec37e0be..ebeca11faa48 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -39,8 +39,9 @@ CONFIG_MTD_SA1100=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
CONFIG_NETDEVICES=y
CONFIG_PCMCIA_PCNET=y
CONFIG_PPP=m
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 8ec4dbbb50b0..cbe7faf55245 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -86,6 +86,7 @@ CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
CONFIG_IMX_WEIM=y
CONFIG_CONNECTOR=y
CONFIG_MTD=y
@@ -256,6 +257,7 @@ CONFIG_SND_IMX_SOC=y
CONFIG_SND_SOC_PHYCORE_AC97=y
CONFIG_SND_SOC_EUKREA_TLV320=y
CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_ES8328=y
CONFIG_SND_SOC_IMX_SGTL5000=y
CONFIG_SND_SOC_IMX_SPDIF=y
CONFIG_SND_SOC_IMX_MC13783=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 869faae67201..69cb8f1efcea 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -26,6 +26,7 @@ CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index cf4918a2c51f..bb910d9df6c1 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -127,16 +127,17 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_EEPROM_LEGACY=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_HPT366=y
-CONFIG_BLK_DEV_PDC202XX_NEW=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_ATA=y
CONFIG_SATA_VIA=y
CONFIG_PATA_ARTOP=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_HPT366=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_HPT3X2N=y
+CONFIG_PATA_PDC2027X=y
CONFIG_PATA_IXP4XX_CF=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index ea80e7e867c2..9056284139be 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -29,8 +29,9 @@ CONFIG_SA1100_FIR=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_NET_ETHERNET=y
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index faa2865658ac..8fc6fd09eb6d 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -36,8 +36,6 @@ CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_LART=y
CONFIG_BLK_DEV_RAM=y
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECD=m
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_NET_ETHERNET=y
diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig
index 04efa1b3ef25..e8d26b805be6 100644
--- a/arch/arm/configs/mainstone_defconfig
+++ b/arch/arm/configs/mainstone_defconfig
@@ -27,7 +27,6 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
# CONFIG_MTD_CFI_I1 is not set
CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_IDE=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_SMC91X=y
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index 2658b80fa263..361686a362f1 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -150,7 +150,6 @@ CONFIG_SPI=y
CONFIG_SPI_ATMEL=y
CONFIG_SPI_IMX=y
CONFIG_SPI_ORION=y
-CONFIG_GPIO_SYSFS=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_QNAP=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 30f39acd61bd..b01a43851294 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -173,6 +173,11 @@ CONFIG_CAN_RCAR=m
CONFIG_CAN_XILINXCAN=y
CONFIG_CAN_MCP251X=y
CONFIG_NET_DSA_BCM_SF2=m
+CONFIG_B53=m
+CONFIG_B53_SPI_DRIVER=m
+CONFIG_B53_MDIO_DRIVER=m
+CONFIG_B53_MMAP_DRIVER=m
+CONFIG_B53_SRAB_DRIVER=m
CONFIG_CAN_SUN4I=y
CONFIG_BT=m
CONFIG_BT_MRVL=m
@@ -235,6 +240,7 @@ CONFIG_HIX5HD2_GMAC=y
CONFIG_SUN4I_EMAC=y
CONFIG_MACB=y
CONFIG_BCMGENET=m
+CONFIG_BGMAC_BCMA=y
CONFIG_SYSTEMPORT=m
CONFIG_NET_CALXEDA_XGMAC=y
CONFIG_GIANFAR=y
@@ -404,7 +410,6 @@ 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
CONFIG_GPIO_DWAPB=y
@@ -450,7 +455,6 @@ CONFIG_RCAR_THERMAL=y
CONFIG_ARMADA_THERMAL=y
CONFIG_DAVINCI_WATCHDOG=m
CONFIG_EXYNOS_THERMAL=m
-CONFIG_ST_THERMAL_SYSCFG=y
CONFIG_ST_THERMAL_MEMMAP=y
CONFIG_WATCHDOG=y
CONFIG_DA9063_WATCHDOG=m
@@ -467,6 +471,7 @@ CONFIG_MESON_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
CONFIG_BCM2835_WDT=y
+CONFIG_BCM47XX_WATCHDOG=y
CONFIG_BCM7038_WDT=m
CONFIG_BCM_KONA_WDT=y
CONFIG_MFD_ACT8945A=y
@@ -561,7 +566,9 @@ CONFIG_VIDEO_EXYNOS4_FIMC_IS=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
+CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_STI_BDISP=m
+CONFIG_VIDEO_STI_HVA=m
CONFIG_VIDEO_RENESAS_JPU=m
CONFIG_VIDEO_RENESAS_VSP1=m
CONFIG_V4L_TEST_DRIVERS=y
@@ -572,6 +579,7 @@ CONFIG_DRM=y
CONFIG_DRM_I2C_ADV7511=m
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
+CONFIG_DRM_DUMB_VGA_DAC=m
CONFIG_DRM_NXP_PTN3460=m
CONFIG_DRM_PARADE_PS8622=m
CONFIG_DRM_NOUVEAU=m
@@ -802,6 +810,10 @@ CONFIG_KEYBOARD_NVEC=y
CONFIG_SERIO_NVEC_PS2=y
CONFIG_NVEC_POWER=y
CONFIG_NVEC_PAZ00=y
+CONFIG_BCMA=y
+CONFIG_BCMA_HOST_SOC=y
+CONFIG_BCMA_DRIVER_GMAC_CMN=y
+CONFIG_BCMA_DRIVER_GPIO=y
CONFIG_QCOM_GSBI=y
CONFIG_QCOM_PM=y
CONFIG_QCOM_SMEM=y
@@ -868,9 +880,7 @@ CONFIG_PHY_ROCKCHIP_DP=m
CONFIG_PHY_ROCKCHIP_USB=m
CONFIG_PHY_QCOM_APQ8064_SATA=m
CONFIG_PHY_MIPHY28LP=y
-CONFIG_PHY_MIPHY365X=y
CONFIG_PHY_RCAR_GEN2=m
-CONFIG_PHY_STIH41X_USB=y
CONFIG_PHY_STIH407_USB=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
@@ -883,6 +893,8 @@ CONFIG_BCM2835_MBOX=y
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EFI_VARS=m
CONFIG_EFI_CAPSULE_LOADER=m
+CONFIG_CONFIG_BCM47XX_NVRAM=y
+CONFIG_BCM47XX_SPROM=y
CONFIG_EXT4_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 4f3dfb21772b..f1395bbd436c 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -8,7 +8,7 @@ CONFIG_LEDS_CPU=y
CONFIG_DEPRECATED_PARAM_STRUCT=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=0x301"
+CONFIG_CMDLINE="root=0x801"
CONFIG_FPE_NWFPE=y
CONFIG_BINFMT_AOUT=y
CONFIG_NET=y
@@ -27,8 +27,9 @@ CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
CONFIG_PARPORT_PC_SUPERIO=y
CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_WINBOND=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 0c8a78734536..6ffc9844542d 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -96,14 +96,14 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECS=m
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=m
+CONFIG_PATA_PCMCIA=m
CONFIG_NETDEVICES=y
CONFIG_TUN=y
CONFIG_PHYLIB=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 53e1a884a1ea..195c98b85568 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -1,7 +1,6 @@
CONFIG_KERNEL_LZMA=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -40,7 +39,6 @@ CONFIG_ARCH_MULTI_V6=y
CONFIG_POWER_AVS_OMAP=y
CONFIG_POWER_AVS_OMAP_CLASS3=y
CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_MUX_DEBUG=y
CONFIG_ARCH_OMAP2=y
CONFIG_ARCH_OMAP3=y
CONFIG_ARCH_OMAP4=y
@@ -50,7 +48,6 @@ CONFIG_SOC_AM43XX=y
CONFIG_SOC_DRA7XX=y
CONFIG_ARM_THUMBEE=y
CONFIG_ARM_ERRATA_411920=y
-CONFIG_ARM_ERRATA_430973=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_CMA=y
@@ -62,7 +59,6 @@ CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
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=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -205,6 +201,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_TOUCHSCREEN_EDT_FT5X06=m
CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m
CONFIG_TOUCHSCREEN_PIXCIR=m
+CONFIG_TOUCHSCREEN_TSC2004=m
CONFIG_TOUCHSCREEN_TSC2005=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_INPUT_MISC=y
@@ -240,14 +237,14 @@ CONFIG_GPIO_PALMAS=y
CONFIG_GPIO_TWL4030=y
CONFIG_W1=m
CONFIG_HDQ_MASTER_OMAP=m
+CONFIG_POWER_AVS=y
+CONFIG_POWER_RESET=y
CONFIG_BATTERY_BQ27XXX=m
CONFIG_CHARGER_ISP1704=m
CONFIG_CHARGER_TWL4030=m
CONFIG_CHARGER_BQ2415X=m
CONFIG_CHARGER_BQ24190=m
CONFIG_CHARGER_BQ24735=m
-CONFIG_POWER_RESET=y
-CONFIG_POWER_AVS=y
CONFIG_HWMON=m
CONFIG_SENSORS_GPIO_FAN=m
CONFIG_SENSORS_LM75=m
@@ -267,10 +264,13 @@ CONFIG_TWL4030_WATCHDOG=m
CONFIG_MFD_TI_AM335X_TSCADC=m
CONFIG_MFD_PALMAS=y
CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TI_LP873X=y
CONFIG_MFD_TPS65218=y
CONFIG_MFD_TPS65910=y
CONFIG_TWL6040_CORE=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_LP872X=y
+CONFIG_REGULATOR_LP873X=y
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_TI_ABB=y
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 74e9cd759b99..8c3a0108a231 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -161,8 +161,8 @@ CONFIG_APQ_MMCC_8084=y
CONFIG_IPQ_LCC_806X=y
CONFIG_MSM_GCC_8660=y
CONFIG_MSM_LCC_8960=y
-CONFIG_MSM_GCC_9615=y
-CONFIG_MSM_LCC_9615=y
+CONFIG_MDM_GCC_9615=y
+CONFIG_MDM_LCC_9615=y
CONFIG_MSM_MMCC_8960=y
CONFIG_MSM_MMCC_8974=y
CONFIG_HWSPINLOCK_QCOM=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index bc4bfe02e611..4364040ed696 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -219,20 +219,16 @@ CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_UB=m
CONFIG_BLK_DEV_RAM=y
CONFIG_ATA_OVER_ETH=m
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_PLATFORM=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ATA=y
+CONFIG_PATA_PLATFORM=y
CONFIG_NETDEVICES=y
CONFIG_DM9000=y
CONFIG_INPUT_EVDEV=y
diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig
index b0b96942f4bd..e52395629810 100644
--- a/arch/arm/configs/shannon_defconfig
+++ b/arch/arm/configs/shannon_defconfig
@@ -25,7 +25,6 @@ CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_SA1100=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=m
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCMCIA=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index baa07a46a88b..1b0f8ae36fb3 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -2,6 +2,7 @@ CONFIG_SYSVIPC=y
CONFIG_NO_HZ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL_SYSCALL=y
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 9f84be5b3ac5..2e1d254e06a2 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -25,6 +25,7 @@ CONFIG_PCIE_ALTERA_MSI=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_VFP=y
@@ -50,6 +51,10 @@ CONFIG_CAN_DEBUG_DEVICES=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_CADENCE_QUADSPI=y
+CONFIG_OF_OVERLAY=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -101,18 +106,28 @@ CONFIG_DMADEVICES=y
CONFIG_PL330_DMA=y
CONFIG_DMATEST=m
CONFIG_FPGA=y
+CONFIG_FPGA_REGION=y
CONFIG_FPGA_MGR_SOCFPGA=y
+CONFIG_FPGA_MGR_SOCFPGA_A10=y
+CONFIG_FPGA_BRIDGE=y
+CONFIG_SOCFPGA_FPGA_BRIDGE=y
+CONFIG_ALTERA_FREEZE_BRIDGE=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS=y
+CONFIG_AUTOFS4_FS=y
CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y
CONFIG_NTFS_RW=y
CONFIG_TMPFS=y
CONFIG_CONFIGFS_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index a1ede1966baf..d8c529332fb4 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -96,15 +96,13 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_SHARPSL=y
CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_USB_CATC=m
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 1e5ec2a0e4cf..5a72d694662f 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -38,8 +38,7 @@ CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FW_LOADER is not set
# CONFIG_BLK_DEV is not set
CONFIG_EEPROM_93CX6=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
+CONFIG_KEYBOARD_GPIO=y
# CONFIG_VT is not set
# CONFIG_UNIX98_PTYS is not set
# CONFIG_LEGACY_PTYS is not set
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 714da336ec86..dfeee5c51b40 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -98,6 +98,7 @@ CONFIG_MEDIA_RC_SUPPORT=y
CONFIG_RC_DEVICES=y
CONFIG_IR_SUNXI=y
CONFIG_DRM=y
+CONFIG_DRM_DUMB_VGA_DAC=y
CONFIG_DRM_SUN4I=y
CONFIG_FB=y
CONFIG_FB_SIMPLE=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 6012a1ec779f..844eeef5a509 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -1,16 +1,15 @@
CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
CONFIG_IRQ_DOMAIN_DEBUG=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
-CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_DEBUG=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_ELF_CORE is not set
CONFIG_EMBEDDED=y
@@ -24,14 +23,10 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_TEGRA=y
-CONFIG_ARCH_TEGRA_2x_SOC=y
-CONFIG_ARCH_TEGRA_3x_SOC=y
-CONFIG_ARCH_TEGRA_114_SOC=y
-CONFIG_ARCH_TEGRA_124_SOC=y
CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
CONFIG_PCI_MSI=y
CONFIG_PCI_TEGRA=y
-CONFIG_PCIEPORTBUS=y
CONFIG_SMP=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
@@ -41,7 +36,6 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_KEXEC=y
CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPU_IDLE=y
@@ -59,7 +53,6 @@ CONFIG_IP_PNP_RARP=y
CONFIG_INET_ESP=y
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
@@ -86,6 +79,7 @@ CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=64
+CONFIG_TEGRA_GMI=y
CONFIG_MTD=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
@@ -131,8 +125,8 @@ CONFIG_INPUT_MPU3050=y
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_TEGRA=y
CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_TEGRA=y
# CONFIG_HW_RANDOM is not set
# CONFIG_I2C_COMPAT is not set
CONFIG_I2C_CHARDEV=y
@@ -151,11 +145,11 @@ CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PALMAS=y
CONFIG_GPIO_TPS6586X=y
CONFIG_GPIO_TPS65910=y
-CONFIG_BATTERY_SBS=y
-CONFIG_CHARGER_TPS65090=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_GPIO=y
+CONFIG_BATTERY_SBS=y
+CONFIG_CHARGER_TPS65090=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_LM95245=y
CONFIG_WATCHDOG=y
@@ -216,6 +210,7 @@ CONFIG_SND_SOC_TEGRA_WM9712=y
CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
CONFIG_SND_SOC_TEGRA_ALC5632=y
CONFIG_SND_SOC_TEGRA_MAX98090=y
+CONFIG_SND_SOC_TEGRA_SGTL5000=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_TEGRA=y
@@ -262,6 +257,10 @@ CONFIG_NVEC_POWER=y
CONFIG_NVEC_PAZ00=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_ARCH_TEGRA_2x_SOC=y
+CONFIG_ARCH_TEGRA_3x_SOC=y
+CONFIG_ARCH_TEGRA_114_SOC=y
+CONFIG_ARCH_TEGRA_124_SOC=y
CONFIG_MEMORY=y
CONFIG_IIO=y
CONFIG_AK8975=y
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index b7b09189f1c5..e2151a7aaf49 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -4,7 +4,6 @@ CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_PERF_EVENTS=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
@@ -26,7 +25,6 @@ CONFIG_CPU_IDLE=y
CONFIG_ARM_U8500_CPUIDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
-CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -108,18 +106,19 @@ CONFIG_DMADEVICES=y
CONFIG_STE_DMA40=y
CONFIG_HSEM_U8500=y
CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
+CONFIG_IIO_SW_TRIGGER=y
CONFIG_IIO_ST_ACCEL_3AXIS=y
CONFIG_IIO_ST_GYRO_3AXIS=y
CONFIG_BH1780=y
+CONFIG_AK8974=y
CONFIG_IIO_ST_MAGN_3AXIS=y
+CONFIG_IIO_HRTIMER_TRIGGER=y
CONFIG_IIO_ST_PRESS=y
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_EXT4_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 55e0e3ea9cb6..efb21757d41f 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -38,3 +38,6 @@ generic-y += termios.h
generic-y += timex.h
generic-y += trace_clock.h
generic-y += unaligned.h
+
+generated-y += mach-types.h
+generated-y += unistd-nr.h
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index b1ce037e4380..e986b7f717c4 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -9,6 +9,33 @@
#include <asm/memory.h>
#include <asm/param.h> /* HZ */
+/*
+ * Loop (or tick) based delay:
+ *
+ * loops = loops_per_jiffy * jiffies_per_sec * delay_us / us_per_sec
+ *
+ * where:
+ *
+ * jiffies_per_sec = HZ
+ * us_per_sec = 1000000
+ *
+ * Therefore the constant part is HZ / 1000000 which is a small
+ * fractional number. To make this usable with integer math, we
+ * scale up this constant by 2^31, perform the actual multiplication,
+ * and scale the result back down by 2^31 with a simple shift:
+ *
+ * loops = (loops_per_jiffy * delay_us * UDELAY_MULT) >> 31
+ *
+ * where:
+ *
+ * UDELAY_MULT = 2^31 * HZ / 1000000
+ * = (2^31 / 1000000) * HZ
+ * = 2147.483648 * HZ
+ * = 2147 * HZ + 483648 * HZ / 1000000
+ *
+ * 31 is the biggest scale shift value that won't overflow 32 bits for
+ * delay_us * UDELAY_MULT assuming HZ <= 1000 and delay_us <= 2000.
+ */
#define MAX_UDELAY_MS 2
#define UDELAY_MULT UL(2147 * HZ + 483648 * HZ / 1000000)
#define UDELAY_SHIFT 31
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
deleted file mode 100644
index 948178cc6ba8..000000000000
--- a/arch/arm/include/asm/mach-types.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <generated/mach-types.h>
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index ada0d29a660f..076090d2dbf5 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -14,12 +14,7 @@
#define __ASM_ARM_UNISTD_H
#include <uapi/asm/unistd.h>
-
-/*
- * This may need to be greater than __NR_last_syscall+1 in order to
- * account for the padding in the syscall table
- */
-#define __NR_syscalls (400)
+#include <asm/unistd-nr.h>
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
@@ -52,4 +47,23 @@
#define __IGNORE_fadvise64_64
#define __IGNORE_migrate_pages
+#ifdef __ARM_EABI__
+/*
+ * The following syscalls are obsolete and no longer available for EABI:
+ * __NR_time
+ * __NR_umount
+ * __NR_stime
+ * __NR_alarm
+ * __NR_utime
+ * __NR_getrlimit
+ * __NR_select
+ * __NR_readdir
+ * __NR_mmap
+ * __NR_socketcall
+ * __NR_syscall
+ * __NR_ipc
+ */
+#define __IGNORE_getrlimit
+#endif
+
#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
index a1c05f93d920..46a76cd6acb6 100644
--- a/arch/arm/include/uapi/asm/Kbuild
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -18,3 +18,6 @@ header-y += stat.h
header-y += statfs.h
header-y += swab.h
header-y += unistd.h
+genhdr-y += unistd-common.h
+genhdr-y += unistd-oabi.h
+genhdr-y += unistd-eabi.h
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index 314100a06ccb..28bd456494a3 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -17,412 +17,14 @@
#if defined(__thumb__) || defined(__ARM_EABI__)
#define __NR_SYSCALL_BASE 0
+#include <asm/unistd-eabi.h>
#else
#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
+#include <asm/unistd-oabi.h>
#endif
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
-#define __NR_exit (__NR_SYSCALL_BASE+ 1)
-#define __NR_fork (__NR_SYSCALL_BASE+ 2)
-#define __NR_read (__NR_SYSCALL_BASE+ 3)
-#define __NR_write (__NR_SYSCALL_BASE+ 4)
-#define __NR_open (__NR_SYSCALL_BASE+ 5)
-#define __NR_close (__NR_SYSCALL_BASE+ 6)
- /* 7 was sys_waitpid */
-#define __NR_creat (__NR_SYSCALL_BASE+ 8)
-#define __NR_link (__NR_SYSCALL_BASE+ 9)
-#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
-#define __NR_execve (__NR_SYSCALL_BASE+ 11)
-#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
-#define __NR_time (__NR_SYSCALL_BASE+ 13)
-#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
-#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
-#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
- /* 17 was sys_break */
- /* 18 was sys_stat */
-#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
-#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
-#define __NR_mount (__NR_SYSCALL_BASE+ 21)
-#define __NR_umount (__NR_SYSCALL_BASE+ 22)
-#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
-#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
-#define __NR_stime (__NR_SYSCALL_BASE+ 25)
-#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
-#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
- /* 28 was sys_fstat */
-#define __NR_pause (__NR_SYSCALL_BASE+ 29)
-#define __NR_utime (__NR_SYSCALL_BASE+ 30)
- /* 31 was sys_stty */
- /* 32 was sys_gtty */
-#define __NR_access (__NR_SYSCALL_BASE+ 33)
-#define __NR_nice (__NR_SYSCALL_BASE+ 34)
- /* 35 was sys_ftime */
-#define __NR_sync (__NR_SYSCALL_BASE+ 36)
-#define __NR_kill (__NR_SYSCALL_BASE+ 37)
-#define __NR_rename (__NR_SYSCALL_BASE+ 38)
-#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
-#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
-#define __NR_dup (__NR_SYSCALL_BASE+ 41)
-#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
-#define __NR_times (__NR_SYSCALL_BASE+ 43)
- /* 44 was sys_prof */
-#define __NR_brk (__NR_SYSCALL_BASE+ 45)
-#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
-#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
- /* 48 was sys_signal */
-#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
-#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
-#define __NR_acct (__NR_SYSCALL_BASE+ 51)
-#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
- /* 53 was sys_lock */
-#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
-#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
- /* 56 was sys_mpx */
-#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
- /* 58 was sys_ulimit */
- /* 59 was sys_olduname */
-#define __NR_umask (__NR_SYSCALL_BASE+ 60)
-#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
-#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
-#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
-#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
-#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
-#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
-#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
- /* 68 was sys_sgetmask */
- /* 69 was sys_ssetmask */
-#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
-#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
-#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
-#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
-#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
-#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
-#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
-#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
-#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
-#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
-#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
-#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
-#define __NR_select (__NR_SYSCALL_BASE+ 82)
-#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
- /* 84 was sys_lstat */
-#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
-#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
-#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
-#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
-#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
-#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
-#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
-#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
-#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
-#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
-#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
-#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
-#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
- /* 98 was sys_profil */
-#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
-#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
- /* 101 was sys_ioperm */
-#define __NR_socketcall (__NR_SYSCALL_BASE+102)
-#define __NR_syslog (__NR_SYSCALL_BASE+103)
-#define __NR_setitimer (__NR_SYSCALL_BASE+104)
-#define __NR_getitimer (__NR_SYSCALL_BASE+105)
-#define __NR_stat (__NR_SYSCALL_BASE+106)
-#define __NR_lstat (__NR_SYSCALL_BASE+107)
-#define __NR_fstat (__NR_SYSCALL_BASE+108)
- /* 109 was sys_uname */
- /* 110 was sys_iopl */
-#define __NR_vhangup (__NR_SYSCALL_BASE+111)
- /* 112 was sys_idle */
-#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
-#define __NR_wait4 (__NR_SYSCALL_BASE+114)
-#define __NR_swapoff (__NR_SYSCALL_BASE+115)
-#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
-#define __NR_ipc (__NR_SYSCALL_BASE+117)
-#define __NR_fsync (__NR_SYSCALL_BASE+118)
-#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
-#define __NR_clone (__NR_SYSCALL_BASE+120)
-#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
-#define __NR_uname (__NR_SYSCALL_BASE+122)
- /* 123 was sys_modify_ldt */
-#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
-#define __NR_mprotect (__NR_SYSCALL_BASE+125)
-#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
- /* 127 was sys_create_module */
-#define __NR_init_module (__NR_SYSCALL_BASE+128)
-#define __NR_delete_module (__NR_SYSCALL_BASE+129)
- /* 130 was sys_get_kernel_syms */
-#define __NR_quotactl (__NR_SYSCALL_BASE+131)
-#define __NR_getpgid (__NR_SYSCALL_BASE+132)
-#define __NR_fchdir (__NR_SYSCALL_BASE+133)
-#define __NR_bdflush (__NR_SYSCALL_BASE+134)
-#define __NR_sysfs (__NR_SYSCALL_BASE+135)
-#define __NR_personality (__NR_SYSCALL_BASE+136)
- /* 137 was sys_afs_syscall */
-#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
-#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
-#define __NR__llseek (__NR_SYSCALL_BASE+140)
-#define __NR_getdents (__NR_SYSCALL_BASE+141)
-#define __NR__newselect (__NR_SYSCALL_BASE+142)
-#define __NR_flock (__NR_SYSCALL_BASE+143)
-#define __NR_msync (__NR_SYSCALL_BASE+144)
-#define __NR_readv (__NR_SYSCALL_BASE+145)
-#define __NR_writev (__NR_SYSCALL_BASE+146)
-#define __NR_getsid (__NR_SYSCALL_BASE+147)
-#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
-#define __NR__sysctl (__NR_SYSCALL_BASE+149)
-#define __NR_mlock (__NR_SYSCALL_BASE+150)
-#define __NR_munlock (__NR_SYSCALL_BASE+151)
-#define __NR_mlockall (__NR_SYSCALL_BASE+152)
-#define __NR_munlockall (__NR_SYSCALL_BASE+153)
-#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
-#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
-#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
-#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
-#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
-#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
-#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
-#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
-#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
-#define __NR_mremap (__NR_SYSCALL_BASE+163)
-#define __NR_setresuid (__NR_SYSCALL_BASE+164)
-#define __NR_getresuid (__NR_SYSCALL_BASE+165)
- /* 166 was sys_vm86 */
- /* 167 was sys_query_module */
-#define __NR_poll (__NR_SYSCALL_BASE+168)
-#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
-#define __NR_setresgid (__NR_SYSCALL_BASE+170)
-#define __NR_getresgid (__NR_SYSCALL_BASE+171)
-#define __NR_prctl (__NR_SYSCALL_BASE+172)
-#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
-#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
-#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
-#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
-#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
-#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
-#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
-#define __NR_pread64 (__NR_SYSCALL_BASE+180)
-#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
-#define __NR_chown (__NR_SYSCALL_BASE+182)
-#define __NR_getcwd (__NR_SYSCALL_BASE+183)
-#define __NR_capget (__NR_SYSCALL_BASE+184)
-#define __NR_capset (__NR_SYSCALL_BASE+185)
-#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
-#define __NR_sendfile (__NR_SYSCALL_BASE+187)
- /* 188 reserved */
- /* 189 reserved */
-#define __NR_vfork (__NR_SYSCALL_BASE+190)
-#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
-#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
-#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
-#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
-#define __NR_stat64 (__NR_SYSCALL_BASE+195)
-#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
-#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
-#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
-#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
-#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
-#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
-#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
-#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
-#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
-#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
-#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
-#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
-#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
-#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
-#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
-#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
-#define __NR_chown32 (__NR_SYSCALL_BASE+212)
-#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
-#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
-#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
-#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
-#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
-#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
-#define __NR_mincore (__NR_SYSCALL_BASE+219)
-#define __NR_madvise (__NR_SYSCALL_BASE+220)
-#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
- /* 222 for tux */
- /* 223 is unused */
-#define __NR_gettid (__NR_SYSCALL_BASE+224)
-#define __NR_readahead (__NR_SYSCALL_BASE+225)
-#define __NR_setxattr (__NR_SYSCALL_BASE+226)
-#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
-#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
-#define __NR_getxattr (__NR_SYSCALL_BASE+229)
-#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
-#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
-#define __NR_listxattr (__NR_SYSCALL_BASE+232)
-#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
-#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
-#define __NR_removexattr (__NR_SYSCALL_BASE+235)
-#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
-#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
-#define __NR_tkill (__NR_SYSCALL_BASE+238)
-#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
-#define __NR_futex (__NR_SYSCALL_BASE+240)
-#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
-#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
-#define __NR_io_setup (__NR_SYSCALL_BASE+243)
-#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
-#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
-#define __NR_io_submit (__NR_SYSCALL_BASE+246)
-#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
-#define __NR_exit_group (__NR_SYSCALL_BASE+248)
-#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
-#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
-#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
-#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
-#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
- /* 254 for set_thread_area */
- /* 255 for get_thread_area */
-#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
-#define __NR_timer_create (__NR_SYSCALL_BASE+257)
-#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
-#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
-#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
-#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
-#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
-#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
-#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
-#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
-#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
-#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
-#define __NR_tgkill (__NR_SYSCALL_BASE+268)
-#define __NR_utimes (__NR_SYSCALL_BASE+269)
-#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
-#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
-#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
-#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
-#define __NR_mq_open (__NR_SYSCALL_BASE+274)
-#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
-#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
-#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
-#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
-#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
-#define __NR_waitid (__NR_SYSCALL_BASE+280)
-#define __NR_socket (__NR_SYSCALL_BASE+281)
-#define __NR_bind (__NR_SYSCALL_BASE+282)
-#define __NR_connect (__NR_SYSCALL_BASE+283)
-#define __NR_listen (__NR_SYSCALL_BASE+284)
-#define __NR_accept (__NR_SYSCALL_BASE+285)
-#define __NR_getsockname (__NR_SYSCALL_BASE+286)
-#define __NR_getpeername (__NR_SYSCALL_BASE+287)
-#define __NR_socketpair (__NR_SYSCALL_BASE+288)
-#define __NR_send (__NR_SYSCALL_BASE+289)
-#define __NR_sendto (__NR_SYSCALL_BASE+290)
-#define __NR_recv (__NR_SYSCALL_BASE+291)
-#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
-#define __NR_shutdown (__NR_SYSCALL_BASE+293)
-#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
-#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
-#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
-#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
-#define __NR_semop (__NR_SYSCALL_BASE+298)
-#define __NR_semget (__NR_SYSCALL_BASE+299)
-#define __NR_semctl (__NR_SYSCALL_BASE+300)
-#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
-#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
-#define __NR_msgget (__NR_SYSCALL_BASE+303)
-#define __NR_msgctl (__NR_SYSCALL_BASE+304)
-#define __NR_shmat (__NR_SYSCALL_BASE+305)
-#define __NR_shmdt (__NR_SYSCALL_BASE+306)
-#define __NR_shmget (__NR_SYSCALL_BASE+307)
-#define __NR_shmctl (__NR_SYSCALL_BASE+308)
-#define __NR_add_key (__NR_SYSCALL_BASE+309)
-#define __NR_request_key (__NR_SYSCALL_BASE+310)
-#define __NR_keyctl (__NR_SYSCALL_BASE+311)
-#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
-#define __NR_vserver (__NR_SYSCALL_BASE+313)
-#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
-#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
-#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
-#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
-#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
-#define __NR_mbind (__NR_SYSCALL_BASE+319)
-#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
-#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
-#define __NR_openat (__NR_SYSCALL_BASE+322)
-#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
-#define __NR_mknodat (__NR_SYSCALL_BASE+324)
-#define __NR_fchownat (__NR_SYSCALL_BASE+325)
-#define __NR_futimesat (__NR_SYSCALL_BASE+326)
-#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
-#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
-#define __NR_renameat (__NR_SYSCALL_BASE+329)
-#define __NR_linkat (__NR_SYSCALL_BASE+330)
-#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
-#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
-#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
-#define __NR_faccessat (__NR_SYSCALL_BASE+334)
-#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
-#define __NR_ppoll (__NR_SYSCALL_BASE+336)
-#define __NR_unshare (__NR_SYSCALL_BASE+337)
-#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
-#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
-#define __NR_splice (__NR_SYSCALL_BASE+340)
-#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
+#include <asm/unistd-common.h>
#define __NR_sync_file_range2 __NR_arm_sync_file_range
-#define __NR_tee (__NR_SYSCALL_BASE+342)
-#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
-#define __NR_move_pages (__NR_SYSCALL_BASE+344)
-#define __NR_getcpu (__NR_SYSCALL_BASE+345)
-#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
-#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
-#define __NR_utimensat (__NR_SYSCALL_BASE+348)
-#define __NR_signalfd (__NR_SYSCALL_BASE+349)
-#define __NR_timerfd_create (__NR_SYSCALL_BASE+350)
-#define __NR_eventfd (__NR_SYSCALL_BASE+351)
-#define __NR_fallocate (__NR_SYSCALL_BASE+352)
-#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353)
-#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354)
-#define __NR_signalfd4 (__NR_SYSCALL_BASE+355)
-#define __NR_eventfd2 (__NR_SYSCALL_BASE+356)
-#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357)
-#define __NR_dup3 (__NR_SYSCALL_BASE+358)
-#define __NR_pipe2 (__NR_SYSCALL_BASE+359)
-#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
-#define __NR_preadv (__NR_SYSCALL_BASE+361)
-#define __NR_pwritev (__NR_SYSCALL_BASE+362)
-#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
-#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
-#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
-#define __NR_accept4 (__NR_SYSCALL_BASE+366)
-#define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
-#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
-#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
-#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370)
-#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371)
-#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
-#define __NR_syncfs (__NR_SYSCALL_BASE+373)
-#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
-#define __NR_setns (__NR_SYSCALL_BASE+375)
-#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
-#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
-#define __NR_kcmp (__NR_SYSCALL_BASE+378)
-#define __NR_finit_module (__NR_SYSCALL_BASE+379)
-#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
-#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
-#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
-#define __NR_seccomp (__NR_SYSCALL_BASE+383)
-#define __NR_getrandom (__NR_SYSCALL_BASE+384)
-#define __NR_memfd_create (__NR_SYSCALL_BASE+385)
-#define __NR_bpf (__NR_SYSCALL_BASE+386)
-#define __NR_execveat (__NR_SYSCALL_BASE+387)
-#define __NR_userfaultfd (__NR_SYSCALL_BASE+388)
-#define __NR_membarrier (__NR_SYSCALL_BASE+389)
-#define __NR_mlock2 (__NR_SYSCALL_BASE+390)
-#define __NR_copy_file_range (__NR_SYSCALL_BASE+391)
-#define __NR_preadv2 (__NR_SYSCALL_BASE+392)
-#define __NR_pwritev2 (__NR_SYSCALL_BASE+393)
-#define __NR_pkey_mprotect (__NR_SYSCALL_BASE+394)
-#define __NR_pkey_alloc (__NR_SYSCALL_BASE+395)
-#define __NR_pkey_free (__NR_SYSCALL_BASE+396)
/*
* The following SWIs are ARM private.
@@ -434,24 +36,4 @@
#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
-/*
- * The following syscalls are obsolete and no longer available for EABI.
- */
-#if !defined(__KERNEL__)
-#if defined(__ARM_EABI__)
-#undef __NR_time
-#undef __NR_umount
-#undef __NR_stime
-#undef __NR_alarm
-#undef __NR_utime
-#undef __NR_getrlimit
-#undef __NR_select
-#undef __NR_readdir
-#undef __NR_mmap
-#undef __NR_socketcall
-#undef __NR_syscall
-#undef __NR_ipc
-#endif
-#endif
-
#endif /* _UAPI__ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
deleted file mode 100644
index 08030b18f10a..000000000000
--- a/arch/arm/kernel/calls.S
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * linux/arch/arm/kernel/calls.S
- *
- * Copyright (C) 1995-2005 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This file is included thrice in entry-common.S
- */
-/* 0 */ CALL(sys_restart_syscall)
- CALL(sys_exit)
- CALL(sys_fork)
- CALL(sys_read)
- CALL(sys_write)
-/* 5 */ CALL(sys_open)
- CALL(sys_close)
- CALL(sys_ni_syscall) /* was sys_waitpid */
- CALL(sys_creat)
- CALL(sys_link)
-/* 10 */ CALL(sys_unlink)
- CALL(sys_execve)
- CALL(sys_chdir)
- CALL(OBSOLETE(sys_time)) /* used by libc4 */
- CALL(sys_mknod)
-/* 15 */ CALL(sys_chmod)
- CALL(sys_lchown16)
- CALL(sys_ni_syscall) /* was sys_break */
- CALL(sys_ni_syscall) /* was sys_stat */
- CALL(sys_lseek)
-/* 20 */ CALL(sys_getpid)
- CALL(sys_mount)
- CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
- CALL(sys_setuid16)
- CALL(sys_getuid16)
-/* 25 */ CALL(OBSOLETE(sys_stime))
- CALL(sys_ptrace)
- CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
- CALL(sys_ni_syscall) /* was sys_fstat */
- CALL(sys_pause)
-/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
- CALL(sys_ni_syscall) /* was sys_stty */
- CALL(sys_ni_syscall) /* was sys_getty */
- CALL(sys_access)
- CALL(sys_nice)
-/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */
- CALL(sys_sync)
- CALL(sys_kill)
- CALL(sys_rename)
- CALL(sys_mkdir)
-/* 40 */ CALL(sys_rmdir)
- CALL(sys_dup)
- CALL(sys_pipe)
- CALL(sys_times)
- CALL(sys_ni_syscall) /* was sys_prof */
-/* 45 */ CALL(sys_brk)
- CALL(sys_setgid16)
- CALL(sys_getgid16)
- CALL(sys_ni_syscall) /* was sys_signal */
- CALL(sys_geteuid16)
-/* 50 */ CALL(sys_getegid16)
- CALL(sys_acct)
- CALL(sys_umount)
- CALL(sys_ni_syscall) /* was sys_lock */
- CALL(sys_ioctl)
-/* 55 */ CALL(sys_fcntl)
- CALL(sys_ni_syscall) /* was sys_mpx */
- CALL(sys_setpgid)
- CALL(sys_ni_syscall) /* was sys_ulimit */
- CALL(sys_ni_syscall) /* was sys_olduname */
-/* 60 */ CALL(sys_umask)
- CALL(sys_chroot)
- CALL(sys_ustat)
- CALL(sys_dup2)
- CALL(sys_getppid)
-/* 65 */ CALL(sys_getpgrp)
- CALL(sys_setsid)
- CALL(sys_sigaction)
- CALL(sys_ni_syscall) /* was sys_sgetmask */
- CALL(sys_ni_syscall) /* was sys_ssetmask */
-/* 70 */ CALL(sys_setreuid16)
- CALL(sys_setregid16)
- CALL(sys_sigsuspend)
- CALL(sys_sigpending)
- CALL(sys_sethostname)
-/* 75 */ CALL(sys_setrlimit)
- CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
- CALL(sys_getrusage)
- CALL(sys_gettimeofday)
- CALL(sys_settimeofday)
-/* 80 */ CALL(sys_getgroups16)
- CALL(sys_setgroups16)
- CALL(OBSOLETE(sys_old_select)) /* used by libc4 */
- CALL(sys_symlink)
- CALL(sys_ni_syscall) /* was sys_lstat */
-/* 85 */ CALL(sys_readlink)
- CALL(sys_uselib)
- CALL(sys_swapon)
- CALL(sys_reboot)
- CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */
-/* 90 */ CALL(OBSOLETE(sys_old_mmap)) /* used by libc4 */
- CALL(sys_munmap)
- CALL(sys_truncate)
- CALL(sys_ftruncate)
- CALL(sys_fchmod)
-/* 95 */ CALL(sys_fchown16)
- CALL(sys_getpriority)
- CALL(sys_setpriority)
- CALL(sys_ni_syscall) /* was sys_profil */
- CALL(sys_statfs)
-/* 100 */ CALL(sys_fstatfs)
- CALL(sys_ni_syscall) /* sys_ioperm */
- CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
- CALL(sys_syslog)
- CALL(sys_setitimer)
-/* 105 */ CALL(sys_getitimer)
- CALL(sys_newstat)
- CALL(sys_newlstat)
- CALL(sys_newfstat)
- CALL(sys_ni_syscall) /* was sys_uname */
-/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
- CALL(sys_vhangup)
- CALL(sys_ni_syscall)
- CALL(OBSOLETE(sys_syscall)) /* call a syscall */
- CALL(sys_wait4)
-/* 115 */ CALL(sys_swapoff)
- CALL(sys_sysinfo)
- CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
- CALL(sys_fsync)
- CALL(sys_sigreturn_wrapper)
-/* 120 */ CALL(sys_clone)
- CALL(sys_setdomainname)
- CALL(sys_newuname)
- CALL(sys_ni_syscall) /* modify_ldt */
- CALL(sys_adjtimex)
-/* 125 */ CALL(sys_mprotect)
- CALL(sys_sigprocmask)
- CALL(sys_ni_syscall) /* was sys_create_module */
- CALL(sys_init_module)
- CALL(sys_delete_module)
-/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */
- CALL(sys_quotactl)
- CALL(sys_getpgid)
- CALL(sys_fchdir)
- CALL(sys_bdflush)
-/* 135 */ CALL(sys_sysfs)
- CALL(sys_personality)
- CALL(sys_ni_syscall) /* reserved for afs_syscall */
- CALL(sys_setfsuid16)
- CALL(sys_setfsgid16)
-/* 140 */ CALL(sys_llseek)
- CALL(sys_getdents)
- CALL(sys_select)
- CALL(sys_flock)
- CALL(sys_msync)
-/* 145 */ CALL(sys_readv)
- CALL(sys_writev)
- CALL(sys_getsid)
- CALL(sys_fdatasync)
- CALL(sys_sysctl)
-/* 150 */ CALL(sys_mlock)
- CALL(sys_munlock)
- CALL(sys_mlockall)
- CALL(sys_munlockall)
- CALL(sys_sched_setparam)
-/* 155 */ CALL(sys_sched_getparam)
- CALL(sys_sched_setscheduler)
- CALL(sys_sched_getscheduler)
- CALL(sys_sched_yield)
- CALL(sys_sched_get_priority_max)
-/* 160 */ CALL(sys_sched_get_priority_min)
- CALL(sys_sched_rr_get_interval)
- CALL(sys_nanosleep)
- CALL(sys_mremap)
- CALL(sys_setresuid16)
-/* 165 */ CALL(sys_getresuid16)
- CALL(sys_ni_syscall) /* vm86 */
- CALL(sys_ni_syscall) /* was sys_query_module */
- CALL(sys_poll)
- CALL(sys_ni_syscall) /* was nfsservctl */
-/* 170 */ CALL(sys_setresgid16)
- CALL(sys_getresgid16)
- CALL(sys_prctl)
- CALL(sys_rt_sigreturn_wrapper)
- CALL(sys_rt_sigaction)
-/* 175 */ CALL(sys_rt_sigprocmask)
- CALL(sys_rt_sigpending)
- CALL(sys_rt_sigtimedwait)
- CALL(sys_rt_sigqueueinfo)
- CALL(sys_rt_sigsuspend)
-/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
- CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
- CALL(sys_chown16)
- CALL(sys_getcwd)
- CALL(sys_capget)
-/* 185 */ CALL(sys_capset)
- CALL(sys_sigaltstack)
- CALL(sys_sendfile)
- CALL(sys_ni_syscall) /* getpmsg */
- CALL(sys_ni_syscall) /* putpmsg */
-/* 190 */ CALL(sys_vfork)
- CALL(sys_getrlimit)
- CALL(sys_mmap2)
- CALL(ABI(sys_truncate64, sys_oabi_truncate64))
- CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
-/* 195 */ CALL(ABI(sys_stat64, sys_oabi_stat64))
- CALL(ABI(sys_lstat64, sys_oabi_lstat64))
- CALL(ABI(sys_fstat64, sys_oabi_fstat64))
- CALL(sys_lchown)
- CALL(sys_getuid)
-/* 200 */ CALL(sys_getgid)
- CALL(sys_geteuid)
- CALL(sys_getegid)
- CALL(sys_setreuid)
- CALL(sys_setregid)
-/* 205 */ CALL(sys_getgroups)
- CALL(sys_setgroups)
- CALL(sys_fchown)
- CALL(sys_setresuid)
- CALL(sys_getresuid)
-/* 210 */ CALL(sys_setresgid)
- CALL(sys_getresgid)
- CALL(sys_chown)
- CALL(sys_setuid)
- CALL(sys_setgid)
-/* 215 */ CALL(sys_setfsuid)
- CALL(sys_setfsgid)
- CALL(sys_getdents64)
- CALL(sys_pivot_root)
- CALL(sys_mincore)
-/* 220 */ CALL(sys_madvise)
- CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
- CALL(sys_ni_syscall) /* TUX */
- CALL(sys_ni_syscall)
- CALL(sys_gettid)
-/* 225 */ CALL(ABI(sys_readahead, sys_oabi_readahead))
- CALL(sys_setxattr)
- CALL(sys_lsetxattr)
- CALL(sys_fsetxattr)
- CALL(sys_getxattr)
-/* 230 */ CALL(sys_lgetxattr)
- CALL(sys_fgetxattr)
- CALL(sys_listxattr)
- CALL(sys_llistxattr)
- CALL(sys_flistxattr)
-/* 235 */ CALL(sys_removexattr)
- CALL(sys_lremovexattr)
- CALL(sys_fremovexattr)
- CALL(sys_tkill)
- CALL(sys_sendfile64)
-/* 240 */ CALL(sys_futex)
- CALL(sys_sched_setaffinity)
- CALL(sys_sched_getaffinity)
- CALL(sys_io_setup)
- CALL(sys_io_destroy)
-/* 245 */ CALL(sys_io_getevents)
- CALL(sys_io_submit)
- CALL(sys_io_cancel)
- CALL(sys_exit_group)
- CALL(sys_lookup_dcookie)
-/* 250 */ CALL(sys_epoll_create)
- CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
- CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
- CALL(sys_remap_file_pages)
- CALL(sys_ni_syscall) /* sys_set_thread_area */
-/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
- CALL(sys_set_tid_address)
- CALL(sys_timer_create)
- CALL(sys_timer_settime)
- CALL(sys_timer_gettime)
-/* 260 */ CALL(sys_timer_getoverrun)
- CALL(sys_timer_delete)
- CALL(sys_clock_settime)
- CALL(sys_clock_gettime)
- CALL(sys_clock_getres)
-/* 265 */ CALL(sys_clock_nanosleep)
- CALL(sys_statfs64_wrapper)
- CALL(sys_fstatfs64_wrapper)
- CALL(sys_tgkill)
- CALL(sys_utimes)
-/* 270 */ CALL(sys_arm_fadvise64_64)
- CALL(sys_pciconfig_iobase)
- CALL(sys_pciconfig_read)
- CALL(sys_pciconfig_write)
- CALL(sys_mq_open)
-/* 275 */ CALL(sys_mq_unlink)
- CALL(sys_mq_timedsend)
- CALL(sys_mq_timedreceive)
- CALL(sys_mq_notify)
- CALL(sys_mq_getsetattr)
-/* 280 */ CALL(sys_waitid)
- CALL(sys_socket)
- CALL(ABI(sys_bind, sys_oabi_bind))
- CALL(ABI(sys_connect, sys_oabi_connect))
- CALL(sys_listen)
-/* 285 */ CALL(sys_accept)
- CALL(sys_getsockname)
- CALL(sys_getpeername)
- CALL(sys_socketpair)
- CALL(sys_send)
-/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto))
- CALL(sys_recv)
- CALL(sys_recvfrom)
- CALL(sys_shutdown)
- CALL(sys_setsockopt)
-/* 295 */ CALL(sys_getsockopt)
- CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
- CALL(sys_recvmsg)
- CALL(ABI(sys_semop, sys_oabi_semop))
- CALL(sys_semget)
-/* 300 */ CALL(sys_semctl)
- CALL(sys_msgsnd)
- CALL(sys_msgrcv)
- CALL(sys_msgget)
- CALL(sys_msgctl)
-/* 305 */ CALL(sys_shmat)
- CALL(sys_shmdt)
- CALL(sys_shmget)
- CALL(sys_shmctl)
- CALL(sys_add_key)
-/* 310 */ CALL(sys_request_key)
- CALL(sys_keyctl)
- CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
-/* vserver */ CALL(sys_ni_syscall)
- CALL(sys_ioprio_set)
-/* 315 */ CALL(sys_ioprio_get)
- CALL(sys_inotify_init)
- CALL(sys_inotify_add_watch)
- CALL(sys_inotify_rm_watch)
- CALL(sys_mbind)
-/* 320 */ CALL(sys_get_mempolicy)
- CALL(sys_set_mempolicy)
- CALL(sys_openat)
- CALL(sys_mkdirat)
- CALL(sys_mknodat)
-/* 325 */ CALL(sys_fchownat)
- CALL(sys_futimesat)
- CALL(ABI(sys_fstatat64, sys_oabi_fstatat64))
- CALL(sys_unlinkat)
- CALL(sys_renameat)
-/* 330 */ CALL(sys_linkat)
- CALL(sys_symlinkat)
- CALL(sys_readlinkat)
- CALL(sys_fchmodat)
- CALL(sys_faccessat)
-/* 335 */ CALL(sys_pselect6)
- CALL(sys_ppoll)
- CALL(sys_unshare)
- CALL(sys_set_robust_list)
- CALL(sys_get_robust_list)
-/* 340 */ CALL(sys_splice)
- CALL(sys_sync_file_range2)
- CALL(sys_tee)
- CALL(sys_vmsplice)
- CALL(sys_move_pages)
-/* 345 */ CALL(sys_getcpu)
- CALL(sys_epoll_pwait)
- CALL(sys_kexec_load)
- CALL(sys_utimensat)
- CALL(sys_signalfd)
-/* 350 */ CALL(sys_timerfd_create)
- CALL(sys_eventfd)
- CALL(sys_fallocate)
- CALL(sys_timerfd_settime)
- CALL(sys_timerfd_gettime)
-/* 355 */ CALL(sys_signalfd4)
- CALL(sys_eventfd2)
- CALL(sys_epoll_create1)
- CALL(sys_dup3)
- CALL(sys_pipe2)
-/* 360 */ CALL(sys_inotify_init1)
- CALL(sys_preadv)
- CALL(sys_pwritev)
- CALL(sys_rt_tgsigqueueinfo)
- CALL(sys_perf_event_open)
-/* 365 */ CALL(sys_recvmmsg)
- CALL(sys_accept4)
- CALL(sys_fanotify_init)
- CALL(sys_fanotify_mark)
- CALL(sys_prlimit64)
-/* 370 */ CALL(sys_name_to_handle_at)
- CALL(sys_open_by_handle_at)
- CALL(sys_clock_adjtime)
- CALL(sys_syncfs)
- CALL(sys_sendmmsg)
-/* 375 */ CALL(sys_setns)
- CALL(sys_process_vm_readv)
- CALL(sys_process_vm_writev)
- CALL(sys_kcmp)
- CALL(sys_finit_module)
-/* 380 */ CALL(sys_sched_setattr)
- CALL(sys_sched_getattr)
- CALL(sys_renameat2)
- CALL(sys_seccomp)
- CALL(sys_getrandom)
-/* 385 */ CALL(sys_memfd_create)
- CALL(sys_bpf)
- CALL(sys_execveat)
- CALL(sys_userfaultfd)
- CALL(sys_membarrier)
-/* 390 */ CALL(sys_mlock2)
- CALL(sys_copy_file_range)
- CALL(sys_preadv2)
- CALL(sys_pwritev2)
- CALL(sys_pkey_mprotect)
-/* 395 */ CALL(sys_pkey_alloc)
- CALL(sys_pkey_free)
-#ifndef syscalls_counted
-.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
-#define syscalls_counted
-#endif
-.rept syscalls_padding
- CALL(sys_ni_syscall)
-.endr
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 10c3283d6c19..eb5cd77bf1d8 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -12,6 +12,11 @@
#include <asm/unistd.h>
#include <asm/ftrace.h>
#include <asm/unwind.h>
+#ifdef CONFIG_AEABI
+#include <asm/unistd-oabi.h>
+#endif
+
+ .equ NR_syscalls, __NR_syscalls
#ifdef CONFIG_NEED_RET_TO_USER
#include <mach/entry-macro.S>
@@ -120,21 +125,6 @@ ENTRY(ret_from_fork)
b ret_slow_syscall
ENDPROC(ret_from_fork)
- .equ NR_syscalls,0
-#define CALL(x) .equ NR_syscalls,NR_syscalls+1
-#include "calls.S"
-
-/*
- * Ensure that the system call table is equal to __NR_syscalls,
- * which is the value the rest of the system sees
- */
-.ifne NR_syscalls - __NR_syscalls
-.error "__NR_syscalls is not equal to the size of the syscall table"
-.endif
-
-#undef CALL
-#define CALL(x) .long x
-
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
@@ -291,22 +281,48 @@ __cr_alignment:
#endif
.ltorg
+ .macro syscall_table_start, sym
+ .equ __sys_nr, 0
+ .type \sym, #object
+ENTRY(\sym)
+ .endm
+
+ .macro syscall, nr, func
+ .ifgt __sys_nr - \nr
+ .error "Duplicated/unorded system call entry"
+ .endif
+ .rept \nr - __sys_nr
+ .long sys_ni_syscall
+ .endr
+ .long \func
+ .equ __sys_nr, \nr + 1
+ .endm
+
+ .macro syscall_table_end, sym
+ .ifgt __sys_nr - __NR_syscalls
+ .error "System call table too big"
+ .endif
+ .rept __NR_syscalls - __sys_nr
+ .long sys_ni_syscall
+ .endr
+ .size \sym, . - \sym
+ .endm
+
+#define NATIVE(nr, func) syscall nr, func
+
/*
* This is the syscall table declaration for native ABI syscalls.
* With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
*/
-#define ABI(native, compat) native
+ syscall_table_start sys_call_table
+#define COMPAT(nr, native, compat) syscall nr, native
#ifdef CONFIG_AEABI
-#define OBSOLETE(syscall) sys_ni_syscall
+#include <calls-eabi.S>
#else
-#define OBSOLETE(syscall) syscall
+#include <calls-oabi.S>
#endif
-
- .type sys_call_table, #object
-ENTRY(sys_call_table)
-#include "calls.S"
-#undef ABI
-#undef OBSOLETE
+#undef COMPAT
+ syscall_table_end sys_call_table
/*============================================================================
* Special system call wrappers
@@ -407,14 +423,10 @@ ENDPROC(sys_oabi_readahead)
* Let's declare a second syscall table for old ABI binaries
* using the compatibility syscall entries.
*/
-#define ABI(native, compat) compat
-#define OBSOLETE(syscall) syscall
-
- .type sys_oabi_call_table, #object
-ENTRY(sys_oabi_call_table)
-#include "calls.S"
-#undef ABI
-#undef OBSOLETE
+ syscall_table_start sys_oabi_call_table
+#define COMPAT(nr, native, compat) syscall nr, compat
+#include <calls-oabi.S>
+ syscall_table_end sys_oabi_call_table
#endif
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index ec279d161b32..ebf47d91b804 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -12,6 +12,7 @@
*/
#include <linux/cpu.h>
+#include <linux/cpufreq.h>
#include <linux/cpumask.h>
#include <linux/export.h>
#include <linux/init.h>
@@ -21,7 +22,9 @@
#include <linux/of.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/cpu.h>
#include <asm/cputype.h>
#include <asm/topology.h>
@@ -41,6 +44,7 @@
* updated during this sequence.
*/
static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
+static DEFINE_MUTEX(cpu_scale_mutex);
unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
{
@@ -52,6 +56,65 @@ static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
per_cpu(cpu_scale, cpu) = capacity;
}
+#ifdef CONFIG_PROC_SYSCTL
+static ssize_t cpu_capacity_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct cpu *cpu = container_of(dev, struct cpu, dev);
+
+ return sprintf(buf, "%lu\n",
+ arch_scale_cpu_capacity(NULL, cpu->dev.id));
+}
+
+static ssize_t cpu_capacity_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct cpu *cpu = container_of(dev, struct cpu, dev);
+ int this_cpu = cpu->dev.id, i;
+ unsigned long new_capacity;
+ ssize_t ret;
+
+ if (count) {
+ ret = kstrtoul(buf, 0, &new_capacity);
+ if (ret)
+ return ret;
+ if (new_capacity > SCHED_CAPACITY_SCALE)
+ return -EINVAL;
+
+ mutex_lock(&cpu_scale_mutex);
+ for_each_cpu(i, &cpu_topology[this_cpu].core_sibling)
+ set_capacity_scale(i, new_capacity);
+ mutex_unlock(&cpu_scale_mutex);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(cpu_capacity);
+
+static int register_cpu_capacity_sysctl(void)
+{
+ int i;
+ struct device *cpu;
+
+ for_each_possible_cpu(i) {
+ cpu = get_cpu_device(i);
+ if (!cpu) {
+ pr_err("%s: too early to get CPU%d device!\n",
+ __func__, i);
+ continue;
+ }
+ device_create_file(cpu, &dev_attr_cpu_capacity);
+ }
+
+ return 0;
+}
+subsys_initcall(register_cpu_capacity_sysctl);
+#endif
+
#ifdef CONFIG_OF
struct cpu_efficiency {
const char *compatible;
@@ -78,6 +141,146 @@ static unsigned long *__cpu_capacity;
#define cpu_capacity(cpu) __cpu_capacity[cpu]
static unsigned long middle_capacity = 1;
+static bool cap_from_dt = true;
+static u32 *raw_capacity;
+static bool cap_parsing_failed;
+static u32 capacity_scale;
+
+static int __init parse_cpu_capacity(struct device_node *cpu_node, int cpu)
+{
+ int ret = 1;
+ u32 cpu_capacity;
+
+ if (cap_parsing_failed)
+ return !ret;
+
+ ret = of_property_read_u32(cpu_node,
+ "capacity-dmips-mhz",
+ &cpu_capacity);
+ if (!ret) {
+ if (!raw_capacity) {
+ raw_capacity = kcalloc(num_possible_cpus(),
+ sizeof(*raw_capacity),
+ GFP_KERNEL);
+ if (!raw_capacity) {
+ pr_err("cpu_capacity: failed to allocate memory for raw capacities\n");
+ cap_parsing_failed = true;
+ return !ret;
+ }
+ }
+ capacity_scale = max(cpu_capacity, capacity_scale);
+ raw_capacity[cpu] = cpu_capacity;
+ pr_debug("cpu_capacity: %s cpu_capacity=%u (raw)\n",
+ cpu_node->full_name, raw_capacity[cpu]);
+ } else {
+ if (raw_capacity) {
+ pr_err("cpu_capacity: missing %s raw capacity\n",
+ cpu_node->full_name);
+ pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
+ }
+ cap_parsing_failed = true;
+ kfree(raw_capacity);
+ }
+
+ return !ret;
+}
+
+static void normalize_cpu_capacity(void)
+{
+ u64 capacity;
+ int cpu;
+
+ if (!raw_capacity || cap_parsing_failed)
+ return;
+
+ pr_debug("cpu_capacity: capacity_scale=%u\n", capacity_scale);
+ mutex_lock(&cpu_scale_mutex);
+ for_each_possible_cpu(cpu) {
+ capacity = (raw_capacity[cpu] << SCHED_CAPACITY_SHIFT)
+ / capacity_scale;
+ set_capacity_scale(cpu, capacity);
+ pr_debug("cpu_capacity: CPU%d cpu_capacity=%lu\n",
+ cpu, arch_scale_cpu_capacity(NULL, cpu));
+ }
+ mutex_unlock(&cpu_scale_mutex);
+}
+
+#ifdef CONFIG_CPU_FREQ
+static cpumask_var_t cpus_to_visit;
+static bool cap_parsing_done;
+static void parsing_done_workfn(struct work_struct *work);
+static DECLARE_WORK(parsing_done_work, parsing_done_workfn);
+
+static int
+init_cpu_capacity_callback(struct notifier_block *nb,
+ unsigned long val,
+ void *data)
+{
+ struct cpufreq_policy *policy = data;
+ int cpu;
+
+ if (cap_parsing_failed || cap_parsing_done)
+ return 0;
+
+ switch (val) {
+ case CPUFREQ_NOTIFY:
+ pr_debug("cpu_capacity: init cpu capacity for CPUs [%*pbl] (to_visit=%*pbl)\n",
+ cpumask_pr_args(policy->related_cpus),
+ cpumask_pr_args(cpus_to_visit));
+ cpumask_andnot(cpus_to_visit,
+ cpus_to_visit,
+ policy->related_cpus);
+ for_each_cpu(cpu, policy->related_cpus) {
+ raw_capacity[cpu] = arch_scale_cpu_capacity(NULL, cpu) *
+ policy->cpuinfo.max_freq / 1000UL;
+ capacity_scale = max(raw_capacity[cpu], capacity_scale);
+ }
+ if (cpumask_empty(cpus_to_visit)) {
+ normalize_cpu_capacity();
+ kfree(raw_capacity);
+ pr_debug("cpu_capacity: parsing done\n");
+ cap_parsing_done = true;
+ schedule_work(&parsing_done_work);
+ }
+ }
+ return 0;
+}
+
+static struct notifier_block init_cpu_capacity_notifier = {
+ .notifier_call = init_cpu_capacity_callback,
+};
+
+static int __init register_cpufreq_notifier(void)
+{
+ if (cap_parsing_failed)
+ return -EINVAL;
+
+ if (!alloc_cpumask_var(&cpus_to_visit, GFP_KERNEL)) {
+ pr_err("cpu_capacity: failed to allocate memory for cpus_to_visit\n");
+ return -ENOMEM;
+ }
+ cpumask_copy(cpus_to_visit, cpu_possible_mask);
+
+ return cpufreq_register_notifier(&init_cpu_capacity_notifier,
+ CPUFREQ_POLICY_NOTIFIER);
+}
+core_initcall(register_cpufreq_notifier);
+
+static void parsing_done_workfn(struct work_struct *work)
+{
+ cpufreq_unregister_notifier(&init_cpu_capacity_notifier,
+ CPUFREQ_POLICY_NOTIFIER);
+}
+
+#else
+static int __init free_raw_capacity(void)
+{
+ kfree(raw_capacity);
+
+ return 0;
+}
+core_initcall(free_raw_capacity);
+#endif
/*
* Iterate all CPUs' descriptor in DT and compute the efficiency
@@ -99,6 +302,12 @@ static void __init parse_dt_topology(void)
__cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
GFP_NOWAIT);
+ cn = of_find_node_by_path("/cpus");
+ if (!cn) {
+ pr_err("No CPU information found in DT\n");
+ return;
+ }
+
for_each_possible_cpu(cpu) {
const u32 *rate;
int len;
@@ -110,6 +319,13 @@ static void __init parse_dt_topology(void)
continue;
}
+ if (parse_cpu_capacity(cn, cpu)) {
+ of_node_put(cn);
+ continue;
+ }
+
+ cap_from_dt = false;
+
for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
if (of_device_is_compatible(cn, cpu_eff->compatible))
break;
@@ -151,6 +367,8 @@ static void __init parse_dt_topology(void)
middle_capacity = ((max_capacity / 3)
>> (SCHED_CAPACITY_SHIFT-1)) + 1;
+ if (cap_from_dt && !cap_parsing_failed)
+ normalize_cpu_capacity();
}
/*
@@ -160,7 +378,7 @@ static void __init parse_dt_topology(void)
*/
static void update_cpu_capacity(unsigned int cpu)
{
- if (!cpu_capacity(cpu))
+ if (!cpu_capacity(cpu) || cap_from_dt)
return;
set_capacity_scale(cpu, cpu_capacity(cpu) / middle_capacity);
diff --git a/arch/arm/lib/delay-loop.S b/arch/arm/lib/delay-loop.S
index 792c59d885bc..c766694e929c 100644
--- a/arch/arm/lib/delay-loop.S
+++ b/arch/arm/lib/delay-loop.S
@@ -17,24 +17,23 @@
.LC1: .word UDELAY_MULT
/*
+ * loops = r0 * HZ * loops_per_jiffy / 1000000
+ *
* r0 <= 2000
* HZ <= 1000
*/
ENTRY(__loop_udelay)
ldr r2, .LC1
- mul r0, r2, r0
-ENTRY(__loop_const_udelay) @ 0 <= r0 <= 0x7fffff06
+ mul r0, r2, r0 @ r0 = delay_us * UDELAY_MULT
+ENTRY(__loop_const_udelay) @ 0 <= r0 <= 0xfffffaf0
ldr r2, .LC0
ldr r2, [r2]
- umull r1, r0, r2, r0
- adds r1, r1, #0xffffffff
- adcs r0, r0, r0
+ umull r1, r0, r2, r0 @ r0-r1 = r0 * loops_per_jiffy
+ adds r1, r1, #0xffffffff @ rounding up ...
+ adcs r0, r0, r0 @ and right shift by 31
reteq lr
-/*
- * loops = r0 * HZ * loops_per_jiffy / 1000000
- */
.align 3
@ Delay routine
diff --git a/arch/arm/mach-artpec/Kconfig b/arch/arm/mach-artpec/Kconfig
index 6cbe5a2eabab..85a962abb77f 100644
--- a/arch/arm/mach-artpec/Kconfig
+++ b/arch/arm/mach-artpec/Kconfig
@@ -14,6 +14,7 @@ config MACH_ARTPEC6
select HAVE_ARM_ARCH_TIMER
select HAVE_ARM_SCU
select HAVE_ARM_TWD if SMP
+ select MFD_SYSCON
help
Support for Axis ARTPEC-6 ARM Cortex A9 Platform
diff --git a/arch/arm/mach-bcm/bcm_5301x.c b/arch/arm/mach-bcm/bcm_5301x.c
index c8830a2b0d60..fe067f6cebb6 100644
--- a/arch/arm/mach-bcm/bcm_5301x.c
+++ b/arch/arm/mach-bcm/bcm_5301x.c
@@ -9,14 +9,42 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
+#include <asm/siginfo.h>
+#include <asm/signal.h>
+
+#define FSR_EXTERNAL (1 << 12)
+#define FSR_READ (0 << 10)
+#define FSR_IMPRECISE 0x0406
static const char *const bcm5301x_dt_compat[] __initconst = {
"brcm,bcm4708",
NULL,
};
+static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ /*
+ * We want to ignore aborts forwarded from the PCIe bus that are
+ * expected and shouldn't really be passed by the PCIe controller.
+ * The biggest disadvantage is the same FSR code may be reported when
+ * reading non-existing APB register and we shouldn't ignore that.
+ */
+ if (fsr == (FSR_EXTERNAL | FSR_READ | FSR_IMPRECISE))
+ return 0;
+
+ return 1;
+}
+
+static void __init bcm5301x_init_early(void)
+{
+ hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
+ "imprecise external abort");
+}
+
DT_MACHINE_START(BCM5301X, "BCM5301X")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
.dt_compat = bcm5301x_dt_compat,
+ .init_early = bcm5301x_init_early,
MACHINE_END
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index da4c336b4637..0a2e6da45f28 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -36,5 +36,7 @@ obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
# Power Management
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
-obj-$(CONFIG_SUSPEND) += pm.o sleep.o
obj-$(CONFIG_HAVE_CLK) += pm_domain.o
+ifeq ($(CONFIG_SUSPEND),y)
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += pm.o sleep.o
+endif
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 3d8cf8cbd98a..58075627c6df 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -14,6 +14,7 @@
#include <linux/console.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
@@ -27,6 +28,7 @@
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
#include <linux/platform_data/usb-davinci.h>
+#include <linux/regulator/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -106,43 +108,24 @@ static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
static __init void da830_evm_usb_init(void)
{
- u32 cfgchip2;
int ret;
- /*
- * Set up USB clock/mode in the CFGCHIP2 register.
- * FYI: CFGCHIP2 is 0x0000ef00 initially.
- */
- cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
- /* USB2.0 PHY reference clock is 24 MHz */
- cfgchip2 &= ~CFGCHIP2_REFFREQ;
- cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
-
- /*
- * Select internal reference clock for USB 2.0 PHY
- * and use it as a clock source for USB 1.1 PHY
- * (this is the default setting anyway).
- */
- cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
- cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX;
-
- /*
- * We have to override VBUS/ID signals when MUSB is configured into the
- * host-only mode -- ID pin will float if no cable is connected, so the
- * controller won't be able to drive VBUS thinking that it's a B-device.
- * Otherwise, we want to use the OTG mode and enable VBUS comparators.
- */
- cfgchip2 &= ~CFGCHIP2_OTGMODE;
-#ifdef CONFIG_USB_MUSB_HOST
- cfgchip2 |= CFGCHIP2_FORCE_HOST;
-#else
- cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
-#endif
+ /* USB_REFCLKIN is not used. */
+ ret = da8xx_register_usb20_phy_clk(false);
+ if (ret)
+ pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
+ __func__, ret);
- __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ ret = da8xx_register_usb11_phy_clk(false);
+ if (ret)
+ pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
+ __func__, ret);
+
+ ret = da8xx_register_usb_phy();
+ if (ret)
+ pr_warn("%s: USB PHY registration failed: %d\n",
+ __func__, ret);
- /* USB_REFCLKIN is not used. */
ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
if (ret)
pr_warn("%s: USB 2.0 PinMux setup failed: %d\n", __func__, ret);
@@ -222,22 +205,16 @@ static const short da830_evm_mmc_sd_pins[] = {
-1
};
-#define DA830_MMCSD_WP_PIN GPIO_TO_PIN(2, 1)
-#define DA830_MMCSD_CD_PIN GPIO_TO_PIN(2, 2)
-
-static int da830_evm_mmc_get_ro(int index)
-{
- return gpio_get_value(DA830_MMCSD_WP_PIN);
-}
-
-static int da830_evm_mmc_get_cd(int index)
-{
- return !gpio_get_value(DA830_MMCSD_CD_PIN);
-}
+static struct gpiod_lookup_table mmc_gpios_table = {
+ .dev_id = "da830-mmc.0",
+ .table = {
+ /* gpio chip 1 contains gpio range 32-63 */
+ GPIO_LOOKUP("davinci_gpio.1", 2, "cd", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("davinci_gpio.1", 1, "wp", GPIO_ACTIVE_LOW),
+ },
+};
static struct davinci_mmc_config da830_evm_mmc_config = {
- .get_ro = da830_evm_mmc_get_ro,
- .get_cd = da830_evm_mmc_get_cd,
.wires = 8,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
@@ -253,26 +230,12 @@ static inline void da830_evm_init_mmc(void)
return;
}
- ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP");
- if (ret) {
- pr_warn("%s: can not open GPIO %d\n",
- __func__, DA830_MMCSD_WP_PIN);
- return;
- }
- gpio_direction_input(DA830_MMCSD_WP_PIN);
-
- ret = gpio_request(DA830_MMCSD_CD_PIN, "MMC CD\n");
- if (ret) {
- pr_warn("%s: can not open GPIO %d\n",
- __func__, DA830_MMCSD_CD_PIN);
- return;
- }
- gpio_direction_input(DA830_MMCSD_CD_PIN);
+ gpiod_add_lookup_table(&mmc_gpios_table);
ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
if (ret) {
pr_warn("%s: mmc/sd registration failed: %d\n", __func__, ret);
- gpio_free(DA830_MMCSD_WP_PIN);
+ gpiod_remove_lookup_table(&mmc_gpios_table);
}
}
@@ -588,6 +551,10 @@ static __init void da830_evm_init(void)
struct davinci_soc_info *soc_info = &davinci_soc_info;
int ret;
+ ret = da8xx_register_cfgchip();
+ if (ret)
+ pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
+
ret = da830_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -647,6 +614,8 @@ static __init void da830_evm_init(void)
ret = da8xx_register_spi_bus(0, ARRAY_SIZE(da830evm_spi_info));
if (ret)
pr_warn("%s: spi 0 registration failed: %d\n", __func__, ret);
+
+ regulator_has_full_constraints();
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 8e4539f69fdc..aac3ab1a044f 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
+#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
@@ -56,9 +57,6 @@
#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
-#define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0)
-#define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1)
-
#define DA850_MII_MDIO_CLKEN_PIN GPIO_TO_PIN(2, 6)
static struct mtd_partition da850evm_spiflash_part[] = {
@@ -196,18 +194,6 @@ static struct platform_device da850_evm_norflash_device = {
.resource = da850_evm_norflash_resource,
};
-static struct davinci_pm_config da850_pm_pdata = {
- .sleepcount = 128,
-};
-
-static struct platform_device da850_pm_device = {
- .name = "pm-davinci",
- .dev = {
- .platform_data = &da850_pm_pdata,
- },
- .id = -1,
-};
-
/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
* (128K blocks). It may be used instead of the (default) SPI flash
* to boot, using TI's tools to install the secondary boot loader
@@ -776,19 +762,16 @@ static const short da850_evm_mcasp_pins[] __initconst = {
-1
};
-static int da850_evm_mmc_get_ro(int index)
-{
- return gpio_get_value(DA850_MMCSD_WP_PIN);
-}
-
-static int da850_evm_mmc_get_cd(int index)
-{
- return !gpio_get_value(DA850_MMCSD_CD_PIN);
-}
+static struct gpiod_lookup_table mmc_gpios_table = {
+ .dev_id = "da830-mmc.0",
+ .table = {
+ /* gpio chip 2 contains gpio range 64-95 */
+ GPIO_LOOKUP("davinci_gpio.2", 0, "cd", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("davinci_gpio.2", 1, "wp", GPIO_ACTIVE_LOW),
+ },
+};
static struct davinci_mmc_config da850_mmc_config = {
- .get_ro = da850_evm_mmc_get_ro,
- .get_cd = da850_evm_mmc_get_cd,
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
@@ -1345,6 +1328,10 @@ static __init void da850_evm_init(void)
{
int ret;
+ ret = da8xx_register_cfgchip();
+ if (ret)
+ pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
+
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -1379,17 +1366,7 @@ static __init void da850_evm_init(void)
pr_warn("%s: MMCSD0 mux setup failed: %d\n",
__func__, ret);
- ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n");
- if (ret)
- pr_warn("%s: can not open GPIO %d\n",
- __func__, DA850_MMCSD_CD_PIN);
- gpio_direction_input(DA850_MMCSD_CD_PIN);
-
- ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n");
- if (ret)
- pr_warn("%s: can not open GPIO %d\n",
- __func__, DA850_MMCSD_WP_PIN);
- gpio_direction_input(DA850_MMCSD_WP_PIN);
+ gpiod_add_lookup_table(&mmc_gpios_table);
ret = da8xx_register_mmcsd0(&da850_mmc_config);
if (ret)
@@ -1453,10 +1430,7 @@ static __init void da850_evm_init(void)
if (ret)
pr_warn("%s: cpuidle registration failed: %d\n", __func__, ret);
- ret = da850_register_pm(&da850_pm_device);
- if (ret)
- pr_warn("%s: suspend registration failed: %d\n", __func__, ret);
-
+ davinci_pm_init();
da850_vpif_init();
ret = spi_register_board_info(da850evm_spi_info,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index bc4e63fa9808..b73ce7bae81f 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -498,22 +498,14 @@ static void __init mityomapl138_config_emac(void)
pr_warn("emac registration failed: %d\n", ret);
}
-static struct davinci_pm_config da850_pm_pdata = {
- .sleepcount = 128,
-};
-
-static struct platform_device da850_pm_device = {
- .name = "pm-davinci",
- .dev = {
- .platform_data = &da850_pm_pdata,
- },
- .id = -1,
-};
-
static void __init mityomapl138_init(void)
{
int ret;
+ ret = da8xx_register_cfgchip();
+ if (ret)
+ pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
+
/* for now, no special EDMA channels are reserved */
ret = da850_register_edma(NULL);
if (ret)
@@ -555,9 +547,7 @@ static void __init mityomapl138_init(void)
if (ret)
pr_warn("cpuidle registration failed: %d\n", ret);
- ret = da850_register_pm(&da850_pm_device);
- if (ret)
- pr_warn("suspend registration failed: %d\n", ret);
+ davinci_pm_init();
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index ee624861ca66..41d5500996b2 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -13,7 +13,9 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/platform_data/gpio-davinci.h>
+#include <linux/regulator/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -24,8 +26,6 @@
#include <mach/mux.h>
#define HAWKBOARD_PHY_ID "davinci_mdio-0:07"
-#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
-#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4)
#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13)
@@ -122,19 +122,16 @@ static const short hawk_mmcsd0_pins[] = {
-1
};
-static int da850_hawk_mmc_get_ro(int index)
-{
- return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN);
-}
-
-static int da850_hawk_mmc_get_cd(int index)
-{
- return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN);
-}
+static struct gpiod_lookup_table mmc_gpios_table = {
+ .dev_id = "da830-mmc.0",
+ .table = {
+ /* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/
+ GPIO_LOOKUP("davinci_gpio.1", 28, "cd", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("davinci_gpio.1", 29, "wp", GPIO_ACTIVE_LOW),
+ },
+};
static struct davinci_mmc_config da850_mmc_config = {
- .get_ro = da850_hawk_mmc_get_ro,
- .get_cd = da850_hawk_mmc_get_cd,
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
@@ -150,21 +147,7 @@ static __init void omapl138_hawk_mmc_init(void)
return;
}
- ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN,
- GPIOF_DIR_IN, "MMC CD");
- if (ret < 0) {
- pr_warn("%s: can not open GPIO %d\n",
- __func__, DA850_HAWK_MMCSD_CD_PIN);
- return;
- }
-
- ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN,
- GPIOF_DIR_IN, "MMC WP");
- if (ret < 0) {
- pr_warn("%s: can not open GPIO %d\n",
- __func__, DA850_HAWK_MMCSD_WP_PIN);
- goto mmc_setup_wp_fail;
- }
+ gpiod_add_lookup_table(&mmc_gpios_table);
ret = da8xx_register_mmcsd0(&da850_mmc_config);
if (ret) {
@@ -175,9 +158,7 @@ static __init void omapl138_hawk_mmc_init(void)
return;
mmc_setup_mmcsd_fail:
- gpio_free(DA850_HAWK_MMCSD_WP_PIN);
-mmc_setup_wp_fail:
- gpio_free(DA850_HAWK_MMCSD_CD_PIN);
+ gpiod_remove_lookup_table(&mmc_gpios_table);
}
static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
@@ -243,7 +224,6 @@ static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
static __init void omapl138_hawk_usb_init(void)
{
int ret;
- u32 cfgchip2;
ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
if (ret) {
@@ -251,12 +231,20 @@ static __init void omapl138_hawk_usb_init(void)
return;
}
- /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */
+ ret = da8xx_register_usb20_phy_clk(false);
+ if (ret)
+ pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
+ __func__, ret);
- cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
- cfgchip2 &= ~CFGCHIP2_REFFREQ;
- cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
- __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ ret = da8xx_register_usb11_phy_clk(false);
+ if (ret)
+ pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
+ __func__, ret);
+
+ ret = da8xx_register_usb_phy();
+ if (ret)
+ pr_warn("%s: USB PHY registration failed: %d\n",
+ __func__, ret);
ret = gpio_request_one(DA850_USB1_VBUS_PIN,
GPIOF_DIR_OUT, "USB1 VBUS");
@@ -292,6 +280,10 @@ static __init void omapl138_hawk_init(void)
{
int ret;
+ ret = da8xx_register_cfgchip();
+ if (ret)
+ pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
+
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -317,6 +309,8 @@ static __init void omapl138_hawk_init(void)
if (ret)
pr_warn("%s: dsp/rproc registration failed: %d\n",
__func__, ret);
+
+ regulator_has_full_constraints();
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index 049025f6d531..9f9fbfa6da0d 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -118,6 +118,5 @@ err:
void __init davinci_init_late(void)
{
davinci_cpufreq_init();
- davinci_pm_init();
davinci_clk_disable_unused();
}
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 426fd7477357..073c458d0c67 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -412,7 +412,7 @@ static struct clk_lookup da830_clks[] = {
CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
- CLK(NULL, "usb20", &usb20_clk),
+ CLK("musb-da8xx", "usb20", &usb20_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "aintc", &aintc_clk),
CLK(NULL, "secu_mgr", &secu_mgr_clk),
@@ -420,7 +420,7 @@ static struct clk_lookup da830_clks[] = {
CLK("davinci_mdio.0", "fck", &emac_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK("i2c_davinci.2", NULL, &i2c1_clk),
- CLK(NULL, "usb11", &usb11_clk),
+ CLK("ohci-da8xx", "usb11", &usb11_clk),
CLK(NULL, "emif3", &emif3_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "rmii", &rmii_clk),
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index ed3d0e9f72ac..e770c97ea45c 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -424,6 +424,16 @@ static struct clk ehrpwm_clk = {
.gpsc = 1,
};
+static struct clk ehrpwm0_clk = {
+ .name = "ehrpwm0",
+ .parent = &ehrpwm_clk,
+};
+
+static struct clk ehrpwm1_clk = {
+ .name = "ehrpwm1",
+ .parent = &ehrpwm_clk,
+};
+
#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
static void ehrpwm_tblck_enable(struct clk *clk)
@@ -451,6 +461,16 @@ static struct clk ehrpwm_tbclk = {
.clk_disable = ehrpwm_tblck_disable,
};
+static struct clk ehrpwm0_tbclk = {
+ .name = "ehrpwm0_tbclk",
+ .parent = &ehrpwm_tbclk,
+};
+
+static struct clk ehrpwm1_tbclk = {
+ .name = "ehrpwm1_tbclk",
+ .parent = &ehrpwm_tbclk,
+};
+
static struct clk ecap_clk = {
.name = "ecap",
.parent = &async3_clk,
@@ -458,6 +478,21 @@ static struct clk ecap_clk = {
.gpsc = 1,
};
+static struct clk ecap0_clk = {
+ .name = "ecap0_clk",
+ .parent = &ecap_clk,
+};
+
+static struct clk ecap1_clk = {
+ .name = "ecap1_clk",
+ .parent = &ecap_clk,
+};
+
+static struct clk ecap2_clk = {
+ .name = "ecap2_clk",
+ .parent = &ecap_clk,
+};
+
static struct clk_lookup da850_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll0", &pll0_clk),
@@ -503,16 +538,23 @@ static struct clk_lookup da850_clks[] = {
CLK("da830-mmc.1", NULL, &mmcsd1_clk),
CLK("ti-aemif", NULL, &aemif_clk),
CLK(NULL, "aemif", &aemif_clk),
- CLK(NULL, "usb11", &usb11_clk),
- CLK(NULL, "usb20", &usb20_clk),
+ CLK("ohci-da8xx", "usb11", &usb11_clk),
+ CLK("musb-da8xx", "usb20", &usb20_clk),
CLK("spi_davinci.0", NULL, &spi0_clk),
CLK("spi_davinci.1", NULL, &spi1_clk),
CLK("vpif", NULL, &vpif_clk),
CLK("ahci_da850", NULL, &sata_clk),
CLK("davinci-rproc.0", NULL, &dsp_clk),
- CLK("ehrpwm", "fck", &ehrpwm_clk),
- CLK("ehrpwm", "tbclk", &ehrpwm_tbclk),
- CLK("ecap", "fck", &ecap_clk),
+ CLK(NULL, NULL, &ehrpwm_clk),
+ CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
+ CLK("ehrpwm.1", "fck", &ehrpwm1_clk),
+ CLK(NULL, NULL, &ehrpwm_tbclk),
+ CLK("ehrpwm.0", "tbclk", &ehrpwm0_tbclk),
+ CLK("ehrpwm.1", "tbclk", &ehrpwm1_tbclk),
+ CLK(NULL, NULL, &ecap_clk),
+ CLK("ecap.0", "fck", &ecap0_clk),
+ CLK("ecap.1", "fck", &ecap1_clk),
+ CLK("ecap.2", "fck", &ecap2_clk),
CLK(NULL, NULL, NULL),
};
@@ -1172,44 +1214,6 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
}
#endif
-int __init da850_register_pm(struct platform_device *pdev)
-{
- int ret;
- struct davinci_pm_config *pdata = pdev->dev.platform_data;
-
- ret = davinci_cfg_reg(DA850_RTC_ALARM);
- if (ret)
- return ret;
-
- pdata->ddr2_ctlr_base = da8xx_get_mem_ctlr();
- pdata->deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);
- pdata->ddrpsc_num = DA8XX_LPSC1_EMIF3C;
-
- pdata->cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
- if (!pdata->cpupll_reg_base)
- return -ENOMEM;
-
- pdata->ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
- if (!pdata->ddrpll_reg_base) {
- ret = -ENOMEM;
- goto no_ddrpll_mem;
- }
-
- pdata->ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
- if (!pdata->ddrpsc_reg_base) {
- ret = -ENOMEM;
- goto no_ddrpsc_mem;
- }
-
- return platform_device_register(pdev);
-
-no_ddrpsc_mem:
- iounmap(pdata->ddrpll_reg_base);
-no_ddrpll_mem:
- iounmap(pdata->cpupll_reg_base);
- return ret;
-}
-
/* VPIF resource, platform data */
static u64 da850_vpif_dma_mask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index c9f7e9274aa8..9ee44da6eb7b 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -23,11 +23,11 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,davinci-i2c", 0x01e28000, "i2c_davinci.2", NULL),
OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
- OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL),
- OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap", NULL),
- OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap", NULL),
+ OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm.0", NULL),
+ OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm.1", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap.0", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap.1", NULL),
+ OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap.2", NULL),
OF_DEV_AUXDATA("ti,da830-spi", 0x01c41000, "spi_davinci.0", NULL),
OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
@@ -38,6 +38,10 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
NULL),
OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", NULL),
+ OF_DEV_AUXDATA("ti,da850-tilcdc", 0x01e13000, "da8xx_lcdc.0", NULL),
+ OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
+ OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
+ OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
{}
};
@@ -45,7 +49,19 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
static void __init da850_init_machine(void)
{
+ int ret;
+
+ ret = da8xx_register_usb20_phy_clk(false);
+ if (ret)
+ pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
+ __func__, ret);
+ ret = da8xx_register_usb11_phy_clk(false);
+ if (ret)
+ pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
+ __func__, ret);
+
of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
+ davinci_pm_init();
}
static const char *const da850_boards_compat[] __initconst = {
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index add3771d38f6..c2457b3fdb5f 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -11,6 +11,7 @@
* (at your option) any later version.
*/
#include <linux/init.h>
+#include <linux/platform_data/syscon.h>
#include <linux/platform_device.h>
#include <linux/dma-contiguous.h>
#include <linux/serial_8250.h>
@@ -57,15 +58,6 @@
#define DA8XX_EMAC_RAM_OFFSET 0x0000
#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K
-#define DA8XX_DMA_SPI0_RX EDMA_CTLR_CHAN(0, 14)
-#define DA8XX_DMA_SPI0_TX EDMA_CTLR_CHAN(0, 15)
-#define DA8XX_DMA_MMCSD0_RX EDMA_CTLR_CHAN(0, 16)
-#define DA8XX_DMA_MMCSD0_TX EDMA_CTLR_CHAN(0, 17)
-#define DA8XX_DMA_SPI1_RX EDMA_CTLR_CHAN(0, 18)
-#define DA8XX_DMA_SPI1_TX EDMA_CTLR_CHAN(0, 19)
-#define DA850_DMA_MMCSD1_RX EDMA_CTLR_CHAN(1, 28)
-#define DA850_DMA_MMCSD1_TX EDMA_CTLR_CHAN(1, 29)
-
void __iomem *da8xx_syscfg0_base;
void __iomem *da8xx_syscfg1_base;
@@ -964,16 +956,6 @@ static struct resource da8xx_spi0_resources[] = {
.end = IRQ_DA8XX_SPINT0,
.flags = IORESOURCE_IRQ,
},
- [2] = {
- .start = DA8XX_DMA_SPI0_RX,
- .end = DA8XX_DMA_SPI0_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = DA8XX_DMA_SPI0_TX,
- .end = DA8XX_DMA_SPI0_TX,
- .flags = IORESOURCE_DMA,
- },
};
static struct resource da8xx_spi1_resources[] = {
@@ -987,16 +969,6 @@ static struct resource da8xx_spi1_resources[] = {
.end = IRQ_DA8XX_SPINT1,
.flags = IORESOURCE_IRQ,
},
- [2] = {
- .start = DA8XX_DMA_SPI1_RX,
- .end = DA8XX_DMA_SPI1_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = DA8XX_DMA_SPI1_TX,
- .end = DA8XX_DMA_SPI1_TX,
- .flags = IORESOURCE_DMA,
- },
};
static struct davinci_spi_platform_data da8xx_spi_pdata[] = {
@@ -1089,3 +1061,30 @@ int __init da850_register_sata(unsigned long refclkpn)
return platform_device_register(&da850_sata_device);
}
#endif
+
+static struct syscon_platform_data da8xx_cfgchip_platform_data = {
+ .label = "cfgchip",
+};
+
+static struct resource da8xx_cfgchip_resources[] = {
+ {
+ .start = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP0_REG,
+ .end = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP4_REG + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da8xx_cfgchip_device = {
+ .name = "syscon",
+ .id = -1,
+ .dev = {
+ .platform_data = &da8xx_cfgchip_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(da8xx_cfgchip_resources),
+ .resource = da8xx_cfgchip_resources,
+};
+
+int __init da8xx_register_cfgchip(void)
+{
+ return platform_device_register(&da8xx_cfgchip_device);
+}
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 67d26c5bda0b..3ae70f2909b0 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -36,9 +36,6 @@
#define DM365_MMCSD0_BASE 0x01D11000
#define DM365_MMCSD1_BASE 0x01D00000
-#define DAVINCI_DMA_MMCRXEVT 26
-#define DAVINCI_DMA_MMCTXEVT 27
-
void __iomem *davinci_sysmod_base;
void davinci_map_sysmod(void)
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index d33322ddedab..bd50367f654e 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -397,14 +397,6 @@ static struct resource dm355_spi0_resources[] = {
.start = IRQ_DM355_SPINT0_0,
.flags = IORESOURCE_IRQ,
},
- {
- .start = 17,
- .flags = IORESOURCE_DMA,
- },
- {
- .start = 16,
- .flags = IORESOURCE_DMA,
- },
};
static struct davinci_spi_platform_data dm355_spi0_pdata = {
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index ef3add999263..8be04ec95adf 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -660,14 +660,6 @@ static struct resource dm365_spi0_resources[] = {
.start = IRQ_DM365_SPIINT0_0,
.flags = IORESOURCE_IRQ,
},
- {
- .start = 17,
- .flags = IORESOURCE_DMA,
- },
- {
- .start = 16,
- .flags = IORESOURCE_DMA,
- },
};
static struct platform_device dm365_spi0_device = {
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index f9f9713aacdd..85ff2183b6db 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -61,6 +61,7 @@ extern unsigned int da850_max_speed;
#define DA8XX_CFGCHIP1_REG 0x180
#define DA8XX_CFGCHIP2_REG 0x184
#define DA8XX_CFGCHIP3_REG 0x188
+#define DA8XX_CFGCHIP4_REG 0x18c
#define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000)
#define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x))
@@ -88,8 +89,12 @@ int da850_register_edma(struct edma_rsv_info *rsv[2]);
int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
int da8xx_register_spi_bus(int instance, unsigned num_chipselect);
int da8xx_register_watchdog(void);
+int da8xx_register_usb_phy(void);
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
+int da8xx_register_usb_refclkin(int rate);
+int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
+int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
int da8xx_register_emac(void);
int da8xx_register_uio_pruss(void);
int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
@@ -101,7 +106,6 @@ int da8xx_register_gpio(void *pdata);
int da850_register_cpufreq(char *async_clk);
int da8xx_register_cpuidle(void);
void __iomem *da8xx_get_mem_ctlr(void);
-int da850_register_pm(struct platform_device *pdev);
int da850_register_sata(unsigned long refclkpn);
int da850_register_vpif(void);
int da850_register_vpif_display
@@ -113,6 +117,7 @@ void da8xx_rproc_reserve_cma(void);
int da8xx_register_rproc(void);
int da850_register_gpio(void);
int da830_register_gpio(void);
+int da8xx_register_cfgchip(void);
extern struct platform_device da8xx_serial_device[];
extern struct emac_platform_data da8xx_emac_pdata;
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index 8929569b1f8a..0afd201ab980 100644
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -21,15 +21,22 @@
#include <mach/common.h>
#include <mach/da8xx.h>
-#include "sram.h"
+#include <mach/mux.h>
#include <mach/pm.h>
#include "clock.h"
+#include "psc.h"
+#include "sram.h"
+#define DA850_PLL1_BASE 0x01e1a000
#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF
+#define DEEPSLEEP_SLEEPCOUNT 128
static void (*davinci_sram_suspend) (struct davinci_pm_config *);
-static struct davinci_pm_config *pdata;
+static struct davinci_pm_config pm_config = {
+ .sleepcount = DEEPSLEEP_SLEEPCOUNT,
+ .ddrpsc_num = DA8XX_LPSC1_EMIF3C,
+};
static void davinci_sram_push(void *dest, void *src, unsigned int size)
{
@@ -41,58 +48,58 @@ static void davinci_pm_suspend(void)
{
unsigned val;
- if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+ if (pm_config.cpupll_reg_base != pm_config.ddrpll_reg_base) {
/* Switch CPU PLL to bypass mode */
- val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
- __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
udelay(PLL_BYPASS_TIME);
/* Powerdown CPU PLL */
- val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
val |= PLLCTL_PLLPWRDN;
- __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
}
/* Configure sleep count in deep sleep register */
- val = __raw_readl(pdata->deepsleep_reg);
+ val = __raw_readl(pm_config.deepsleep_reg);
val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
- val |= pdata->sleepcount;
- __raw_writel(val, pdata->deepsleep_reg);
+ val |= pm_config.sleepcount;
+ __raw_writel(val, pm_config.deepsleep_reg);
/* System goes to sleep in this call */
- davinci_sram_suspend(pdata);
+ davinci_sram_suspend(&pm_config);
- if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+ if (pm_config.cpupll_reg_base != pm_config.ddrpll_reg_base) {
/* put CPU PLL in reset */
- val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLRST;
- __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
/* put CPU PLL in power down */
- val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLPWRDN;
- __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
/* wait for CPU PLL reset */
udelay(PLL_RESET_TIME);
/* bring CPU PLL out of reset */
- val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
val |= PLLCTL_PLLRST;
- __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
/* Wait for CPU PLL to lock */
udelay(PLL_LOCK_TIME);
/* Remove CPU PLL from bypass mode */
- val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val = __raw_readl(pm_config.cpupll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLENSRC;
val |= PLLCTL_PLLEN;
- __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ __raw_writel(val, pm_config.cpupll_reg_base + PLLCTL);
}
}
@@ -117,17 +124,36 @@ static const struct platform_suspend_ops davinci_pm_ops = {
.valid = suspend_valid_only_mem,
};
-static int __init davinci_pm_probe(struct platform_device *pdev)
+int __init davinci_pm_init(void)
{
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "cannot get platform data\n");
- return -ENOENT;
+ int ret;
+
+ ret = davinci_cfg_reg(DA850_RTC_ALARM);
+ if (ret)
+ return ret;
+
+ pm_config.ddr2_ctlr_base = da8xx_get_mem_ctlr();
+ pm_config.deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);
+
+ pm_config.cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+ if (!pm_config.cpupll_reg_base)
+ return -ENOMEM;
+
+ pm_config.ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
+ if (!pm_config.ddrpll_reg_base) {
+ ret = -ENOMEM;
+ goto no_ddrpll_mem;
+ }
+
+ pm_config.ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+ if (!pm_config.ddrpsc_reg_base) {
+ ret = -ENOMEM;
+ goto no_ddrpsc_mem;
}
davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
if (!davinci_sram_suspend) {
- dev_err(&pdev->dev, "cannot allocate SRAM memory\n");
+ pr_err("PM: cannot allocate SRAM memory\n");
return -ENOMEM;
}
@@ -136,23 +162,9 @@ static int __init davinci_pm_probe(struct platform_device *pdev)
suspend_set_ops(&davinci_pm_ops);
- return 0;
-}
-
-static int __exit davinci_pm_remove(struct platform_device *pdev)
-{
- sram_free(davinci_sram_suspend, davinci_cpu_suspend_sz);
- return 0;
-}
-
-static struct platform_driver davinci_pm_driver = {
- .driver = {
- .name = "pm-davinci",
- },
- .remove = __exit_p(davinci_pm_remove),
-};
-
-int __init davinci_pm_init(void)
-{
- return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
+no_ddrpsc_mem:
+ iounmap(pm_config.ddrpll_reg_base);
+no_ddrpll_mem:
+ iounmap(pm_config.cpupll_reg_base);
+ return ret;
}
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index f141f5171906..c6feecf7ae24 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -1,21 +1,44 @@
/*
* DA8xx USB
*/
+#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/phy/phy.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_device.h>
#include <linux/usb/musb.h>
+#include <mach/clock.h>
#include <mach/common.h>
#include <mach/cputype.h>
#include <mach/da8xx.h>
#include <mach/irqs.h>
+#include "clock.h"
+
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
-#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
+static struct platform_device da8xx_usb_phy = {
+ .name = "da8xx-usb-phy",
+ .id = -1,
+ .dev = {
+ /*
+ * Setting init_name so that clock lookup will work in
+ * da8xx_register_usb11_phy_clk() even if this device is not
+ * registered yet.
+ */
+ .init_name = "da8xx-usb-phy",
+ },
+};
+
+int __init da8xx_register_usb_phy(void)
+{
+ return platform_device_register(&da8xx_usb_phy);
+}
static struct musb_hdrc_config musb_config = {
.multipoint = true,
@@ -45,10 +68,15 @@ static struct resource da8xx_usb20_resources[] = {
static u64 usb_dmamask = DMA_BIT_MASK(32);
-static struct platform_device usb_dev = {
+static struct platform_device da8xx_usb20_dev = {
.name = "musb-da8xx",
.id = -1,
.dev = {
+ /*
+ * Setting init_name so that clock lookup will work in
+ * usb20_phy_clk_enable() even if this device is not registered.
+ */
+ .init_name = "musb-da8xx",
.platform_data = &usb_data,
.dma_mask = &usb_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
@@ -62,18 +90,9 @@ int __init da8xx_register_usb20(unsigned int mA, unsigned int potpgt)
usb_data.power = mA > 510 ? 255 : mA / 2;
usb_data.potpgt = (potpgt + 1) / 2;
- return platform_device_register(&usb_dev);
-}
-
-#else
-
-int __init da8xx_register_usb20(unsigned int mA, unsigned int potpgt)
-{
- return 0;
+ return platform_device_register(&da8xx_usb20_dev);
}
-#endif /* CONFIG_USB_MUSB_HDRC */
-
static struct resource da8xx_usb11_resources[] = {
[0] = {
.start = DA8XX_USB1_BASE,
@@ -90,8 +109,8 @@ static struct resource da8xx_usb11_resources[] = {
static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
static struct platform_device da8xx_usb11_device = {
- .name = "ohci",
- .id = 0,
+ .name = "ohci-da8xx",
+ .id = -1,
.dev = {
.dma_mask = &da8xx_usb11_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
@@ -105,3 +124,236 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
da8xx_usb11_device.dev.platform_data = pdata;
return platform_device_register(&da8xx_usb11_device);
}
+
+static struct clk usb_refclkin = {
+ .name = "usb_refclkin",
+ .set_rate = davinci_simple_set_rate,
+};
+
+static struct clk_lookup usb_refclkin_lookup =
+ CLK(NULL, "usb_refclkin", &usb_refclkin);
+
+/**
+ * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
+ *
+ * @rate: The clock rate in Hz
+ *
+ * This clock is only needed if the board provides an external USB_REFCLKIN
+ * signal, in which case it will be used as the parent of usb20_phy_clk and/or
+ * usb11_phy_clk.
+ */
+int __init da8xx_register_usb_refclkin(int rate)
+{
+ int ret;
+
+ usb_refclkin.rate = rate;
+ ret = clk_register(&usb_refclkin);
+ if (ret)
+ return ret;
+
+ clkdev_add(&usb_refclkin_lookup);
+
+ return 0;
+}
+
+static void usb20_phy_clk_enable(struct clk *clk)
+{
+ struct clk *usb20_clk;
+ int err;
+ u32 val;
+ u32 timeout = 500000; /* 500 msec */
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
+ if (IS_ERR(usb20_clk)) {
+ pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
+ return;
+ }
+
+ /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
+ err = clk_prepare_enable(usb20_clk);
+ if (err) {
+ pr_err("failed to enable usb20 clk: %d\n", err);
+ clk_put(usb20_clk);
+ return;
+ }
+
+ /*
+ * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
+ * host may use the PLL clock without USB 2.0 OTG being used.
+ */
+ val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
+ val |= CFGCHIP2_PHY_PLLON;
+
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ while (--timeout) {
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ if (val & CFGCHIP2_PHYCLKGD)
+ goto done;
+ udelay(1);
+ }
+
+ pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
+done:
+ clk_disable_unprepare(usb20_clk);
+ clk_put(usb20_clk);
+}
+
+static void usb20_phy_clk_disable(struct clk *clk)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ val |= CFGCHIP2_PHYPWRDN;
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+}
+
+static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* Set the mux depending on the parent clock. */
+ if (parent == &usb_refclkin) {
+ val &= ~CFGCHIP2_USB2PHYCLKMUX;
+ } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
+ val |= CFGCHIP2_USB2PHYCLKMUX;
+ } else {
+ pr_err("Bad parent on USB 2.0 PHY clock\n");
+ return -EINVAL;
+ }
+
+ /* reference frequency also comes from parent clock */
+ val &= ~CFGCHIP2_REFFREQ_MASK;
+ switch (clk_get_rate(parent)) {
+ case 12000000:
+ val |= CFGCHIP2_REFFREQ_12MHZ;
+ break;
+ case 13000000:
+ val |= CFGCHIP2_REFFREQ_13MHZ;
+ break;
+ case 19200000:
+ val |= CFGCHIP2_REFFREQ_19_2MHZ;
+ break;
+ case 20000000:
+ val |= CFGCHIP2_REFFREQ_20MHZ;
+ break;
+ case 24000000:
+ val |= CFGCHIP2_REFFREQ_24MHZ;
+ break;
+ case 26000000:
+ val |= CFGCHIP2_REFFREQ_26MHZ;
+ break;
+ case 38400000:
+ val |= CFGCHIP2_REFFREQ_38_4MHZ;
+ break;
+ case 40000000:
+ val |= CFGCHIP2_REFFREQ_40MHZ;
+ break;
+ case 48000000:
+ val |= CFGCHIP2_REFFREQ_48MHZ;
+ break;
+ default:
+ pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
+ return -EINVAL;
+ }
+
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ return 0;
+}
+
+static struct clk usb20_phy_clk = {
+ .name = "usb20_phy",
+ .clk_enable = usb20_phy_clk_enable,
+ .clk_disable = usb20_phy_clk_disable,
+ .set_parent = usb20_phy_clk_set_parent,
+};
+
+static struct clk_lookup usb20_phy_clk_lookup =
+ CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
+
+/**
+ * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
+ *
+ * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
+ * or "pll0_aux" if false.
+ */
+int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
+{
+ struct clk *parent;
+ int ret = 0;
+
+ parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
+ if (IS_ERR(parent))
+ return PTR_ERR(parent);
+
+ usb20_phy_clk.parent = parent;
+ ret = clk_register(&usb20_phy_clk);
+ if (!ret)
+ clkdev_add(&usb20_phy_clk_lookup);
+
+ clk_put(parent);
+
+ return ret;
+}
+
+static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 val;
+
+ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* Set the USB 1.1 PHY clock mux based on the parent clock. */
+ if (parent == &usb20_phy_clk) {
+ val &= ~CFGCHIP2_USB1PHYCLKMUX;
+ } else if (parent == &usb_refclkin) {
+ val |= CFGCHIP2_USB1PHYCLKMUX;
+ } else {
+ pr_err("Bad parent on USB 1.1 PHY clock\n");
+ return -EINVAL;
+ }
+
+ writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ return 0;
+}
+
+static struct clk usb11_phy_clk = {
+ .name = "usb11_phy",
+ .set_parent = usb11_phy_clk_set_parent,
+};
+
+static struct clk_lookup usb11_phy_clk_lookup =
+ CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
+
+/**
+ * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
+ *
+ * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
+ * or "usb20_phy" if false.
+ */
+int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
+{
+ struct clk *parent;
+ int ret = 0;
+
+ if (use_usb_refclkin)
+ parent = clk_get(NULL, "usb_refclkin");
+ else
+ parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy");
+ if (IS_ERR(parent))
+ return PTR_ERR(parent);
+
+ usb11_phy_clk.parent = parent;
+ ret = clk_register(&usb11_phy_clk);
+ if (!ret)
+ clkdev_add(&usb11_phy_clk_lookup);
+
+ clk_put(parent);
+
+ return ret;
+}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 9155b639c9aa..936c59d0e18b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -557,7 +557,6 @@ config SOC_VF610
bool "Vybrid Family VF610 support"
select ARM_GIC if ARCH_MULTI_V7
select PINCTRL_VF610
- select PL310_ERRATA_769419 if CACHE_L2X0
help
This enables support for Freescale Vybrid VF610 processor.
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c4436d9c52ff..b09a2ec19267 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -43,7 +43,6 @@ int mx21_clocks_init(unsigned long lref, unsigned long fref);
int mx27_clocks_init(unsigned long fref);
int mx31_clocks_init(unsigned long fref);
int mx35_clocks_init(void);
-int mx31_clocks_init_dt(void);
struct platform_device *mxc_register_gpio(char *name, int id,
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
void mxc_set_cpu_type(unsigned int type);
diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c
index 62e6b4fb5370..668d74b72511 100644
--- a/arch/arm/mach-imx/imx31-dt.c
+++ b/arch/arm/mach-imx/imx31-dt.c
@@ -23,11 +23,6 @@ static const char * const imx31_dt_board_compat[] __initconst = {
NULL
};
-static void __init imx31_dt_timer_init(void)
-{
- mx31_clocks_init_dt();
-}
-
/* FIXME: replace with DT binding */
static const struct resource imx31_rnga_res[] __initconst = {
DEFINE_RES_MEM(MX31_RNGA_BASE_ADDR, SZ_16K),
@@ -43,7 +38,6 @@ DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)")
.map_io = mx31_map_io,
.init_early = imx31_init_early,
.init_irq = mx31_init_irq,
- .init_time = imx31_dt_timer_init,
.init_machine = imx31_dt_mach_init,
.dt_compat = imx31_dt_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index 58a2b88233e6..6cb8a22b617d 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -89,6 +89,7 @@ static void __init imx6ul_init_late(void)
static const char * const imx6ul_dt_compat[] __initconst = {
"fsl,imx6ul",
+ "fsl,imx6ull",
NULL,
};
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index db9621c718ec..ba96bf979625 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011,2016 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
*
* The code contained herein is licensed under the GNU General Public
@@ -10,12 +10,16 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/hrtimer.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
+#include <linux/perf_event.h>
+#include <linux/slab.h>
#include "common.h"
@@ -27,8 +31,489 @@
#define BM_MMDC_MDMISC_DDR_TYPE 0x18
#define BP_MMDC_MDMISC_DDR_TYPE 0x3
+#define TOTAL_CYCLES 0x0
+#define BUSY_CYCLES 0x1
+#define READ_ACCESSES 0x2
+#define WRITE_ACCESSES 0x3
+#define READ_BYTES 0x4
+#define WRITE_BYTES 0x5
+
+/* Enables, resets, freezes, overflow profiling*/
+#define DBG_DIS 0x0
+#define DBG_EN 0x1
+#define DBG_RST 0x2
+#define PRF_FRZ 0x4
+#define CYC_OVF 0x8
+#define PROFILE_SEL 0x10
+
+#define MMDC_MADPCR0 0x410
+#define MMDC_MADPSR0 0x418
+#define MMDC_MADPSR1 0x41C
+#define MMDC_MADPSR2 0x420
+#define MMDC_MADPSR3 0x424
+#define MMDC_MADPSR4 0x428
+#define MMDC_MADPSR5 0x42C
+
+#define MMDC_NUM_COUNTERS 6
+
+#define MMDC_FLAG_PROFILE_SEL 0x1
+
+#define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu)
+
static int ddr_type;
+struct fsl_mmdc_devtype_data {
+ unsigned int flags;
+};
+
+static const struct fsl_mmdc_devtype_data imx6q_data = {
+};
+
+static const struct fsl_mmdc_devtype_data imx6qp_data = {
+ .flags = MMDC_FLAG_PROFILE_SEL,
+};
+
+static const struct of_device_id imx_mmdc_dt_ids[] = {
+ { .compatible = "fsl,imx6q-mmdc", .data = (void *)&imx6q_data},
+ { .compatible = "fsl,imx6qp-mmdc", .data = (void *)&imx6qp_data},
+ { /* sentinel */ }
+};
+
+#ifdef CONFIG_PERF_EVENTS
+
+static DEFINE_IDA(mmdc_ida);
+
+PMU_EVENT_ATTR_STRING(total-cycles, mmdc_pmu_total_cycles, "event=0x00")
+PMU_EVENT_ATTR_STRING(busy-cycles, mmdc_pmu_busy_cycles, "event=0x01")
+PMU_EVENT_ATTR_STRING(read-accesses, mmdc_pmu_read_accesses, "event=0x02")
+PMU_EVENT_ATTR_STRING(write-accesses, mmdc_pmu_write_accesses, "config=0x03")
+PMU_EVENT_ATTR_STRING(read-bytes, mmdc_pmu_read_bytes, "event=0x04")
+PMU_EVENT_ATTR_STRING(read-bytes.unit, mmdc_pmu_read_bytes_unit, "MB");
+PMU_EVENT_ATTR_STRING(read-bytes.scale, mmdc_pmu_read_bytes_scale, "0.000001");
+PMU_EVENT_ATTR_STRING(write-bytes, mmdc_pmu_write_bytes, "event=0x05")
+PMU_EVENT_ATTR_STRING(write-bytes.unit, mmdc_pmu_write_bytes_unit, "MB");
+PMU_EVENT_ATTR_STRING(write-bytes.scale, mmdc_pmu_write_bytes_scale, "0.000001");
+
+struct mmdc_pmu {
+ struct pmu pmu;
+ void __iomem *mmdc_base;
+ cpumask_t cpu;
+ struct hrtimer hrtimer;
+ unsigned int active_events;
+ struct device *dev;
+ struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
+ struct hlist_node node;
+ struct fsl_mmdc_devtype_data *devtype_data;
+};
+
+/*
+ * Polling period is set to one second, overflow of total-cycles (the fastest
+ * increasing counter) takes ten seconds so one second is safe
+ */
+static unsigned int mmdc_pmu_poll_period_us = 1000000;
+
+module_param_named(pmu_pmu_poll_period_us, mmdc_pmu_poll_period_us, uint,
+ S_IRUGO | S_IWUSR);
+
+static ktime_t mmdc_pmu_timer_period(void)
+{
+ return ns_to_ktime((u64)mmdc_pmu_poll_period_us * 1000);
+}
+
+static ssize_t mmdc_pmu_cpumask_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mmdc_pmu *pmu_mmdc = dev_get_drvdata(dev);
+
+ return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu);
+}
+
+static struct device_attribute mmdc_pmu_cpumask_attr =
+ __ATTR(cpumask, S_IRUGO, mmdc_pmu_cpumask_show, NULL);
+
+static struct attribute *mmdc_pmu_cpumask_attrs[] = {
+ &mmdc_pmu_cpumask_attr.attr,
+ NULL,
+};
+
+static struct attribute_group mmdc_pmu_cpumask_attr_group = {
+ .attrs = mmdc_pmu_cpumask_attrs,
+};
+
+static struct attribute *mmdc_pmu_events_attrs[] = {
+ &mmdc_pmu_total_cycles.attr.attr,
+ &mmdc_pmu_busy_cycles.attr.attr,
+ &mmdc_pmu_read_accesses.attr.attr,
+ &mmdc_pmu_write_accesses.attr.attr,
+ &mmdc_pmu_read_bytes.attr.attr,
+ &mmdc_pmu_read_bytes_unit.attr.attr,
+ &mmdc_pmu_read_bytes_scale.attr.attr,
+ &mmdc_pmu_write_bytes.attr.attr,
+ &mmdc_pmu_write_bytes_unit.attr.attr,
+ &mmdc_pmu_write_bytes_scale.attr.attr,
+ NULL,
+};
+
+static struct attribute_group mmdc_pmu_events_attr_group = {
+ .name = "events",
+ .attrs = mmdc_pmu_events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-63");
+static struct attribute *mmdc_pmu_format_attrs[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group mmdc_pmu_format_attr_group = {
+ .name = "format",
+ .attrs = mmdc_pmu_format_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+ &mmdc_pmu_events_attr_group,
+ &mmdc_pmu_format_attr_group,
+ &mmdc_pmu_cpumask_attr_group,
+ NULL,
+};
+
+static u32 mmdc_pmu_read_counter(struct mmdc_pmu *pmu_mmdc, int cfg)
+{
+ void __iomem *mmdc_base, *reg;
+
+ mmdc_base = pmu_mmdc->mmdc_base;
+
+ switch (cfg) {
+ case TOTAL_CYCLES:
+ reg = mmdc_base + MMDC_MADPSR0;
+ break;
+ case BUSY_CYCLES:
+ reg = mmdc_base + MMDC_MADPSR1;
+ break;
+ case READ_ACCESSES:
+ reg = mmdc_base + MMDC_MADPSR2;
+ break;
+ case WRITE_ACCESSES:
+ reg = mmdc_base + MMDC_MADPSR3;
+ break;
+ case READ_BYTES:
+ reg = mmdc_base + MMDC_MADPSR4;
+ break;
+ case WRITE_BYTES:
+ reg = mmdc_base + MMDC_MADPSR5;
+ break;
+ default:
+ return WARN_ONCE(1,
+ "invalid configuration %d for mmdc counter", cfg);
+ }
+ return readl(reg);
+}
+
+static int mmdc_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+ struct mmdc_pmu *pmu_mmdc = hlist_entry_safe(node, struct mmdc_pmu, node);
+ int target;
+
+ if (!cpumask_test_and_clear_cpu(cpu, &pmu_mmdc->cpu))
+ return 0;
+
+ target = cpumask_any_but(cpu_online_mask, cpu);
+ if (target >= nr_cpu_ids)
+ return 0;
+
+ perf_pmu_migrate_context(&pmu_mmdc->pmu, cpu, target);
+ cpumask_set_cpu(target, &pmu_mmdc->cpu);
+
+ return 0;
+}
+
+static bool mmdc_pmu_group_event_is_valid(struct perf_event *event,
+ struct pmu *pmu,
+ unsigned long *used_counters)
+{
+ int cfg = event->attr.config;
+
+ if (is_software_event(event))
+ return true;
+
+ if (event->pmu != pmu)
+ return false;
+
+ return !test_and_set_bit(cfg, used_counters);
+}
+
+/*
+ * Each event has a single fixed-purpose counter, so we can only have a
+ * single active event for each at any point in time. Here we just check
+ * for duplicates, and rely on mmdc_pmu_event_init to verify that the HW
+ * event numbers are valid.
+ */
+static bool mmdc_pmu_group_is_valid(struct perf_event *event)
+{
+ struct pmu *pmu = event->pmu;
+ struct perf_event *leader = event->group_leader;
+ struct perf_event *sibling;
+ unsigned long counter_mask = 0;
+
+ set_bit(leader->attr.config, &counter_mask);
+
+ if (event != leader) {
+ if (!mmdc_pmu_group_event_is_valid(event, pmu, &counter_mask))
+ return false;
+ }
+
+ list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ if (!mmdc_pmu_group_event_is_valid(sibling, pmu, &counter_mask))
+ return false;
+ }
+
+ return true;
+}
+
+static int mmdc_pmu_event_init(struct perf_event *event)
+{
+ struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
+ int cfg = event->attr.config;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+ return -EOPNOTSUPP;
+
+ if (event->cpu < 0) {
+ dev_warn(pmu_mmdc->dev, "Can't provide per-task data!\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period)
+ return -EINVAL;
+
+ if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
+ return -EINVAL;
+
+ if (!mmdc_pmu_group_is_valid(event))
+ return -EINVAL;
+
+ event->cpu = cpumask_first(&pmu_mmdc->cpu);
+ return 0;
+}
+
+static void mmdc_pmu_event_update(struct perf_event *event)
+{
+ struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ u64 delta, prev_raw_count, new_raw_count;
+
+ do {
+ prev_raw_count = local64_read(&hwc->prev_count);
+ new_raw_count = mmdc_pmu_read_counter(pmu_mmdc,
+ event->attr.config);
+ } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count);
+
+ delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF;
+
+ local64_add(delta, &event->count);
+}
+
+static void mmdc_pmu_event_start(struct perf_event *event, int flags)
+{
+ struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ void __iomem *mmdc_base, *reg;
+ u32 val;
+
+ mmdc_base = pmu_mmdc->mmdc_base;
+ reg = mmdc_base + MMDC_MADPCR0;
+
+ /*
+ * hrtimer is required because mmdc does not provide an interrupt so
+ * polling is necessary
+ */
+ hrtimer_start(&pmu_mmdc->hrtimer, mmdc_pmu_timer_period(),
+ HRTIMER_MODE_REL_PINNED);
+
+ local64_set(&hwc->prev_count, 0);
+
+ writel(DBG_RST, reg);
+
+ val = DBG_EN;
+ if (pmu_mmdc->devtype_data->flags & MMDC_FLAG_PROFILE_SEL)
+ val |= PROFILE_SEL;
+
+ writel(val, reg);
+}
+
+static int mmdc_pmu_event_add(struct perf_event *event, int flags)
+{
+ struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ int cfg = event->attr.config;
+
+ if (flags & PERF_EF_START)
+ mmdc_pmu_event_start(event, flags);
+
+ if (pmu_mmdc->mmdc_events[cfg] != NULL)
+ return -EAGAIN;
+
+ pmu_mmdc->mmdc_events[cfg] = event;
+ pmu_mmdc->active_events++;
+
+ local64_set(&hwc->prev_count, mmdc_pmu_read_counter(pmu_mmdc, cfg));
+
+ return 0;
+}
+
+static void mmdc_pmu_event_stop(struct perf_event *event, int flags)
+{
+ struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
+ void __iomem *mmdc_base, *reg;
+
+ mmdc_base = pmu_mmdc->mmdc_base;
+ reg = mmdc_base + MMDC_MADPCR0;
+
+ writel(PRF_FRZ, reg);
+ mmdc_pmu_event_update(event);
+}
+
+static void mmdc_pmu_event_del(struct perf_event *event, int flags)
+{
+ struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
+ int cfg = event->attr.config;
+
+ pmu_mmdc->mmdc_events[cfg] = NULL;
+ pmu_mmdc->active_events--;
+
+ if (pmu_mmdc->active_events == 0)
+ hrtimer_cancel(&pmu_mmdc->hrtimer);
+
+ mmdc_pmu_event_stop(event, PERF_EF_UPDATE);
+}
+
+static void mmdc_pmu_overflow_handler(struct mmdc_pmu *pmu_mmdc)
+{
+ int i;
+
+ for (i = 0; i < MMDC_NUM_COUNTERS; i++) {
+ struct perf_event *event = pmu_mmdc->mmdc_events[i];
+
+ if (event)
+ mmdc_pmu_event_update(event);
+ }
+}
+
+static enum hrtimer_restart mmdc_pmu_timer_handler(struct hrtimer *hrtimer)
+{
+ struct mmdc_pmu *pmu_mmdc = container_of(hrtimer, struct mmdc_pmu,
+ hrtimer);
+
+ mmdc_pmu_overflow_handler(pmu_mmdc);
+ hrtimer_forward_now(hrtimer, mmdc_pmu_timer_period());
+
+ return HRTIMER_RESTART;
+}
+
+static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
+ void __iomem *mmdc_base, struct device *dev)
+{
+ int mmdc_num;
+
+ *pmu_mmdc = (struct mmdc_pmu) {
+ .pmu = (struct pmu) {
+ .task_ctx_nr = perf_invalid_context,
+ .attr_groups = attr_groups,
+ .event_init = mmdc_pmu_event_init,
+ .add = mmdc_pmu_event_add,
+ .del = mmdc_pmu_event_del,
+ .start = mmdc_pmu_event_start,
+ .stop = mmdc_pmu_event_stop,
+ .read = mmdc_pmu_event_update,
+ },
+ .mmdc_base = mmdc_base,
+ .dev = dev,
+ .active_events = 0,
+ };
+
+ mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
+
+ return mmdc_num;
+}
+
+static int imx_mmdc_remove(struct platform_device *pdev)
+{
+ struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
+
+ perf_pmu_unregister(&pmu_mmdc->pmu);
+ cpuhp_remove_state_nocalls(CPUHP_ONLINE);
+ kfree(pmu_mmdc);
+ return 0;
+}
+
+static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_base)
+{
+ struct mmdc_pmu *pmu_mmdc;
+ char *name;
+ int mmdc_num;
+ int ret;
+ const struct of_device_id *of_id =
+ of_match_device(imx_mmdc_dt_ids, &pdev->dev);
+
+ pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL);
+ if (!pmu_mmdc) {
+ pr_err("failed to allocate PMU device!\n");
+ return -ENOMEM;
+ }
+
+ mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
+ if (mmdc_num == 0)
+ name = "mmdc";
+ else
+ name = devm_kasprintf(&pdev->dev,
+ GFP_KERNEL, "mmdc%d", mmdc_num);
+
+ pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
+
+ hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ pmu_mmdc->hrtimer.function = mmdc_pmu_timer_handler;
+
+ cpuhp_state_add_instance_nocalls(CPUHP_ONLINE,
+ &pmu_mmdc->node);
+ cpumask_set_cpu(smp_processor_id(), &pmu_mmdc->cpu);
+ ret = cpuhp_setup_state_multi(CPUHP_AP_NOTIFY_ONLINE,
+ "MMDC_ONLINE", NULL,
+ mmdc_pmu_offline_cpu);
+ if (ret) {
+ pr_err("cpuhp_setup_state_multi failure\n");
+ goto pmu_register_err;
+ }
+
+ ret = perf_pmu_register(&(pmu_mmdc->pmu), name, -1);
+ platform_set_drvdata(pdev, pmu_mmdc);
+ if (ret)
+ goto pmu_register_err;
+ return 0;
+
+pmu_register_err:
+ pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret);
+ hrtimer_cancel(&pmu_mmdc->hrtimer);
+ kfree(pmu_mmdc);
+ return ret;
+}
+
+#else
+#define imx_mmdc_remove NULL
+#define imx_mmdc_perf_init(pdev, mmdc_base) 0
+#endif
+
static int imx_mmdc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -62,7 +547,7 @@ static int imx_mmdc_probe(struct platform_device *pdev)
return -EBUSY;
}
- return 0;
+ return imx_mmdc_perf_init(pdev, mmdc_base);
}
int imx_mmdc_get_ddr_type(void)
@@ -70,17 +555,13 @@ int imx_mmdc_get_ddr_type(void)
return ddr_type;
}
-static const struct of_device_id imx_mmdc_dt_ids[] = {
- { .compatible = "fsl,imx6q-mmdc", },
- { /* sentinel */ }
-};
-
static struct platform_driver imx_mmdc_driver = {
.driver = {
.name = "imx-mmdc",
.of_match_table = imx_mmdc_dt_ids,
},
.probe = imx_mmdc_probe,
+ .remove = imx_mmdc_remove,
};
static int __init imx_mmdc_init(void)
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 23b98fd414bf..a1af634f8709 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -27,6 +27,8 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/termios.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -37,11 +39,8 @@
#include "pci_v3.h"
#include "lm.h"
-/* Base address to the AP system controller */
-void __iomem *ap_syscon_base;
-/* Base address to the external bus interface */
-static void __iomem *ebi_base;
-
+/* Regmap to the AP system controller */
+static struct regmap *ap_syscon_map;
/*
* All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -125,6 +124,7 @@ static void integrator_uart_set_mctrl(struct amba_device *dev,
{
unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
u32 phybase = dev->res.start;
+ int ret;
if (phybase == INTEGRATOR_UART0_BASE) {
/* UART0 */
@@ -146,8 +146,17 @@ static void integrator_uart_set_mctrl(struct amba_device *dev,
else
ctrls |= dtr_mask;
- __raw_writel(ctrls, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
- __raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
+ ret = regmap_write(ap_syscon_map,
+ INTEGRATOR_SC_CTRLS_OFFSET,
+ ctrls);
+ if (ret)
+ pr_err("MODEM: unable to write PL010 UART CTRLS\n");
+
+ ret = regmap_write(ap_syscon_map,
+ INTEGRATOR_SC_CTRLC_OFFSET,
+ ctrlc);
+ if (ret)
+ pr_err("MODEM: unable to write PL010 UART CRTLC\n");
}
struct amba_pl010_data ap_uart_data = {
@@ -178,35 +187,32 @@ static const struct of_device_id ap_syscon_match[] = {
{ },
};
-static const struct of_device_id ebi_match[] = {
- { .compatible = "arm,external-bus-interface"},
- { },
-};
-
static void __init ap_init_of(void)
{
- unsigned long sc_dec;
+ u32 sc_dec;
struct device_node *syscon;
- struct device_node *ebi;
+ int ret;
int i;
+ of_platform_default_populate(NULL, ap_auxdata_lookup, NULL);
+
syscon = of_find_matching_node(NULL, ap_syscon_match);
if (!syscon)
return;
- ebi = of_find_matching_node(NULL, ebi_match);
- if (!ebi)
+ ap_syscon_map = syscon_node_to_regmap(syscon);
+ if (IS_ERR(ap_syscon_map)) {
+ pr_crit("could not find Integrator/AP system controller\n");
return;
+ }
- ap_syscon_base = of_iomap(syscon, 0);
- if (!ap_syscon_base)
- return;
- ebi_base = of_iomap(ebi, 0);
- if (!ebi_base)
+ ret = regmap_read(ap_syscon_map,
+ INTEGRATOR_SC_DEC_OFFSET,
+ &sc_dec);
+ if (ret) {
+ pr_crit("could not read from Integrator/AP syscon\n");
return;
+ }
- of_platform_default_populate(NULL, ap_auxdata_lookup, NULL);
-
- sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
for (i = 0; i < 4; i++) {
struct lm_device *lmdev;
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 43ee06d3abe5..b3bd0e137f6d 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -26,7 +26,6 @@
#include <linux/reboot.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
-#include <linux/gpio.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-lpc32xx/clock.h b/arch/arm/mach-lpc32xx/clock.h
deleted file mode 100644
index c0a8434307f7..000000000000
--- a/arch/arm/mach-lpc32xx/clock.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/clock.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the 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.
- */
-
-#ifndef __LPC32XX_CLOCK_H
-#define __LPC32XX_CLOCK_H
-
-struct clk {
- struct list_head node;
- struct clk *parent;
- u32 rate;
- u32 usecount;
-
- int (*set_rate) (struct clk *, unsigned long);
- unsigned long (*round_rate) (struct clk *, unsigned long);
- unsigned long (*get_rate) (struct clk *clk);
- int (*enable) (struct clk *, int);
-
- /* Register address and bit mask for simple clocks */
- void __iomem *enable_reg;
- u32 enable_mask;
-};
-
-#endif
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
index 30c9e64fc65b..02575c2444e4 100644
--- a/arch/arm/mach-lpc32xx/common.h
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -24,7 +24,6 @@
/*
* Other arch specific structures and functions
*/
-extern void __init lpc32xx_init_irq(void);
extern void __init lpc32xx_map_io(void);
extern void __init lpc32xx_serial_init(void);
diff --git a/arch/arm/mach-lpc32xx/include/mach/irqs.h b/arch/arm/mach-lpc32xx/include/mach/irqs.h
deleted file mode 100644
index 00190535df90..000000000000
--- a/arch/arm/mach-lpc32xx/include/mach/irqs.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/include/mach/irqs.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the 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.
- */
-
-#ifndef __ASM_ARM_ARCH_IRQS_H
-#define __ASM_ARM_ARCH_IRQS_H
-
-#define LPC32XX_SIC1_IRQ(n) (32 + (n))
-#define LPC32XX_SIC2_IRQ(n) (64 + (n))
-
-/*
- * MIC interrupts
- */
-#define IRQ_LPC32XX_SUB1IRQ 0
-#define IRQ_LPC32XX_SUB2IRQ 1
-#define IRQ_LPC32XX_PWM3 3
-#define IRQ_LPC32XX_PWM4 4
-#define IRQ_LPC32XX_HSTIMER 5
-#define IRQ_LPC32XX_WATCH 6
-#define IRQ_LPC32XX_UART_IIR3 7
-#define IRQ_LPC32XX_UART_IIR4 8
-#define IRQ_LPC32XX_UART_IIR5 9
-#define IRQ_LPC32XX_UART_IIR6 10
-#define IRQ_LPC32XX_FLASH 11
-#define IRQ_LPC32XX_SD1 13
-#define IRQ_LPC32XX_LCD 14
-#define IRQ_LPC32XX_SD0 15
-#define IRQ_LPC32XX_TIMER0 16
-#define IRQ_LPC32XX_TIMER1 17
-#define IRQ_LPC32XX_TIMER2 18
-#define IRQ_LPC32XX_TIMER3 19
-#define IRQ_LPC32XX_SSP0 20
-#define IRQ_LPC32XX_SSP1 21
-#define IRQ_LPC32XX_I2S0 22
-#define IRQ_LPC32XX_I2S1 23
-#define IRQ_LPC32XX_UART_IIR7 24
-#define IRQ_LPC32XX_UART_IIR2 25
-#define IRQ_LPC32XX_UART_IIR1 26
-#define IRQ_LPC32XX_MSTIMER 27
-#define IRQ_LPC32XX_DMA 28
-#define IRQ_LPC32XX_ETHERNET 29
-#define IRQ_LPC32XX_SUB1FIQ 30
-#define IRQ_LPC32XX_SUB2FIQ 31
-
-/*
- * SIC1 interrupts start at offset 32
- */
-#define IRQ_LPC32XX_JTAG_COMM_TX LPC32XX_SIC1_IRQ(1)
-#define IRQ_LPC32XX_JTAG_COMM_RX LPC32XX_SIC1_IRQ(2)
-#define IRQ_LPC32XX_GPI_28 LPC32XX_SIC1_IRQ(4)
-#define IRQ_LPC32XX_TS_P LPC32XX_SIC1_IRQ(6)
-#define IRQ_LPC32XX_TS_IRQ LPC32XX_SIC1_IRQ(7)
-#define IRQ_LPC32XX_TS_AUX LPC32XX_SIC1_IRQ(8)
-#define IRQ_LPC32XX_SPI2 LPC32XX_SIC1_IRQ(12)
-#define IRQ_LPC32XX_PLLUSB LPC32XX_SIC1_IRQ(13)
-#define IRQ_LPC32XX_PLLHCLK LPC32XX_SIC1_IRQ(14)
-#define IRQ_LPC32XX_PLL397 LPC32XX_SIC1_IRQ(17)
-#define IRQ_LPC32XX_I2C_2 LPC32XX_SIC1_IRQ(18)
-#define IRQ_LPC32XX_I2C_1 LPC32XX_SIC1_IRQ(19)
-#define IRQ_LPC32XX_RTC LPC32XX_SIC1_IRQ(20)
-#define IRQ_LPC32XX_KEY LPC32XX_SIC1_IRQ(22)
-#define IRQ_LPC32XX_SPI1 LPC32XX_SIC1_IRQ(23)
-#define IRQ_LPC32XX_SW LPC32XX_SIC1_IRQ(24)
-#define IRQ_LPC32XX_USB_OTG_TIMER LPC32XX_SIC1_IRQ(25)
-#define IRQ_LPC32XX_USB_OTG_ATX LPC32XX_SIC1_IRQ(26)
-#define IRQ_LPC32XX_USB_HOST LPC32XX_SIC1_IRQ(27)
-#define IRQ_LPC32XX_USB_DEV_DMA LPC32XX_SIC1_IRQ(28)
-#define IRQ_LPC32XX_USB_DEV_LP LPC32XX_SIC1_IRQ(29)
-#define IRQ_LPC32XX_USB_DEV_HP LPC32XX_SIC1_IRQ(30)
-#define IRQ_LPC32XX_USB_I2C LPC32XX_SIC1_IRQ(31)
-
-/*
- * SIC2 interrupts start at offset 64
- */
-#define IRQ_LPC32XX_GPIO_00 LPC32XX_SIC2_IRQ(0)
-#define IRQ_LPC32XX_GPIO_01 LPC32XX_SIC2_IRQ(1)
-#define IRQ_LPC32XX_GPIO_02 LPC32XX_SIC2_IRQ(2)
-#define IRQ_LPC32XX_GPIO_03 LPC32XX_SIC2_IRQ(3)
-#define IRQ_LPC32XX_GPIO_04 LPC32XX_SIC2_IRQ(4)
-#define IRQ_LPC32XX_GPIO_05 LPC32XX_SIC2_IRQ(5)
-#define IRQ_LPC32XX_SPI2_DATAIN LPC32XX_SIC2_IRQ(6)
-#define IRQ_LPC32XX_U2_HCTS LPC32XX_SIC2_IRQ(7)
-#define IRQ_LPC32XX_P0_P1_IRQ LPC32XX_SIC2_IRQ(8)
-#define IRQ_LPC32XX_GPI_08 LPC32XX_SIC2_IRQ(9)
-#define IRQ_LPC32XX_GPI_09 LPC32XX_SIC2_IRQ(10)
-#define IRQ_LPC32XX_GPI_19 LPC32XX_SIC2_IRQ(11)
-#define IRQ_LPC32XX_U7_HCTS LPC32XX_SIC2_IRQ(12)
-#define IRQ_LPC32XX_GPI_07 LPC32XX_SIC2_IRQ(15)
-#define IRQ_LPC32XX_SDIO LPC32XX_SIC2_IRQ(18)
-#define IRQ_LPC32XX_U5_RX LPC32XX_SIC2_IRQ(19)
-#define IRQ_LPC32XX_SPI1_DATAIN LPC32XX_SIC2_IRQ(20)
-#define IRQ_LPC32XX_GPI_00 LPC32XX_SIC2_IRQ(22)
-#define IRQ_LPC32XX_GPI_01 LPC32XX_SIC2_IRQ(23)
-#define IRQ_LPC32XX_GPI_02 LPC32XX_SIC2_IRQ(24)
-#define IRQ_LPC32XX_GPI_03 LPC32XX_SIC2_IRQ(25)
-#define IRQ_LPC32XX_GPI_04 LPC32XX_SIC2_IRQ(26)
-#define IRQ_LPC32XX_GPI_05 LPC32XX_SIC2_IRQ(27)
-#define IRQ_LPC32XX_GPI_06 LPC32XX_SIC2_IRQ(28)
-#define IRQ_LPC32XX_SYSCLK LPC32XX_SIC2_IRQ(31)
-
-#define LPC32XX_NR_IRQS 96
-
-#endif
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 0e4cbbe980eb..6c52bd32610e 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -23,7 +23,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/dma-mapping.h>
-#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c
index 207e81275ff0..62471570d586 100644
--- a/arch/arm/mach-lpc32xx/pm.c
+++ b/arch/arm/mach-lpc32xx/pm.c
@@ -73,7 +73,6 @@
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
-#include "clock.h"
#define TEMP_IRAM_AREA IO_ADDRESS(LPC32XX_IRAM_BASE)
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 21164605b83f..dadae67d79b7 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -1,4 +1,2 @@
-ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
-endif
-obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
+obj-$(CONFIG_SMP) += platsmp.o
+obj-y += mediatek.o
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index afb809509140..45c6b733c881 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -31,6 +31,32 @@ config ARCH_OMAP16XX
select ARCH_OMAP_OTG
select CPU_ARM926T
+config OMAP_MUX
+ bool "OMAP multiplexing support"
+ depends on ARCH_OMAP
+ default y
+ help
+ Pin multiplexing support for OMAP boards. If your bootloader
+ sets the multiplexing correctly, say N. Otherwise, or if unsure,
+ say Y.
+
+config OMAP_MUX_DEBUG
+ bool "Multiplexing debug output"
+ depends on OMAP_MUX
+ help
+ Makes the multiplexing functions print out a lot of debug info.
+ This is useful if you want to find out the correct values of the
+ multiplexing registers.
+
+config OMAP_MUX_WARNINGS
+ bool "Warn about pins the bootloader didn't set up"
+ depends on OMAP_MUX
+ default y
+ help
+ Choose Y here to warn whenever driver initialization logic needs
+ to change the pin multiplexing setup. When there are no warnings
+ printed, it's safe to deselect OMAP_MUX for your product.
+
comment "OMAP Board Type"
depends on ARCH_OMAP1
diff --git a/arch/arm/mach-omap1/i2c.c b/arch/arm/mach-omap1/i2c.c
index 82887d645a6a..32f6c53367bf 100644
--- a/arch/arm/mach-omap1/i2c.c
+++ b/arch/arm/mach-omap1/i2c.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/i2c.h>
#include <linux/i2c-omap.h>
#include <mach/mux.h>
#include "soc.h"
@@ -91,6 +92,88 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata,
return platform_device_register(pdev);
}
+#define OMAP_I2C_MAX_CONTROLLERS 4
+static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
+
+#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
+
+/**
+ * omap_i2c_bus_setup - Process command line options for the I2C bus speed
+ * @str: String of options
+ *
+ * This function allow to override the default I2C bus speed for given I2C
+ * bus with a command line option.
+ *
+ * Format: i2c_bus=bus_id,clkrate (in kHz)
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int __init omap_i2c_bus_setup(char *str)
+{
+ int ints[3];
+
+ get_options(str, 3, ints);
+ if (ints[0] < 2 || ints[1] < 1 ||
+ ints[1] > OMAP_I2C_MAX_CONTROLLERS)
+ return 0;
+ i2c_pdata[ints[1] - 1].clkrate = ints[2];
+ i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP;
+
+ return 1;
+}
+__setup("i2c_bus=", omap_i2c_bus_setup);
+
+/*
+ * Register busses defined in command line but that are not registered with
+ * omap_register_i2c_bus from board initialization code.
+ */
+int __init omap_register_i2c_bus_cmdline(void)
+{
+ int i, err = 0;
+
+ for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++)
+ if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) {
+ i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
+ err = omap_i2c_add_bus(&i2c_pdata[i], i + 1);
+ if (err)
+ goto out;
+ }
+
+out:
+ return err;
+}
+
+/**
+ * omap_register_i2c_bus - register I2C bus with device descriptors
+ * @bus_id: bus id counting from number 1
+ * @clkrate: clock rate of the bus in kHz
+ * @info: pointer into I2C device descriptor table or NULL
+ * @len: number of descriptors in the table
+ *
+ * Returns 0 on success or an error code.
+ */
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+ struct i2c_board_info const *info,
+ unsigned len)
+{
+ int err;
+
+ BUG_ON(bus_id < 1 || bus_id > OMAP_I2C_MAX_CONTROLLERS);
+
+ if (info) {
+ err = i2c_register_board_info(bus_id, info, len);
+ if (err)
+ return err;
+ }
+
+ if (!i2c_pdata[bus_id - 1].clkrate)
+ i2c_pdata[bus_id - 1].clkrate = clkrate;
+
+ i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
+
+ return omap_i2c_add_bus(&i2c_pdata[bus_id - 1], bus_id);
+}
+
static int __init omap_i2c_cmdline(void)
{
return omap_register_i2c_bus_cmdline();
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 5b37ec29996e..469894082fea 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -6,7 +6,7 @@ ccflags-y := -I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-omap/include
# Common support
-obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o timer.o pm.o \
+obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \
common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
omap_device.o omap-headsmp.o sram.o drm.o
@@ -63,9 +63,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap4-restart.o
obj-$(CONFIG_SOC_OMAP5) += omap4-restart.o
obj-$(CONFIG_SOC_DRA7XX) += omap4-restart.o
-# Pin multiplexing
-obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o
-
# SMS/SDRC
obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
@@ -80,7 +77,7 @@ endif
# Power Management
omap-4-5-pm-common = omap-mpuss-lowpower.o
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common)
-obj-$(CONFIG_ARCH_OMAP5) += $(omap-4-5-pm-common)
+obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common)
obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
ifeq ($(CONFIG_PM),y)
@@ -235,26 +232,15 @@ obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
# Platform specific device init code
-omap-flash-$(CONFIG_MTD_NAND_OMAP2) := board-flash.o
-omap-flash-$(CONFIG_MTD_ONENAND_OMAP2) := board-flash.o
-obj-y += $(omap-flash-y) $(omap-flash-m)
-
omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o
obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y)
-obj-y += usb-musb.o
obj-y += omap_phy_internal.o
obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o
-obj-y += usb-host.o
onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o
obj-y += $(onenand-m) $(onenand-y)
nand-$(CONFIG_MTD_NAND_OMAP2) := gpmc-nand.o
obj-y += $(nand-m) $(nand-y)
-
-smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o
-obj-y += $(smsc911x-m) $(smsc911x-y)
-
-obj-y += common-board-devices.o twl-common.o dss-common.o
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
deleted file mode 100644
index 2188dc30e232..000000000000
--- a/arch/arm/mach-omap2/board-flash.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * board-flash.c
- * Modified from mach-omap2/board-3430sdp-flash.c
- *
- * Copyright (C) 2009 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments
- *
- * Vimal Singh <vimalsingh@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/omap-gpmc.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
-
-#include <linux/platform_data/mtd-nand-omap2.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
-
-#include "soc.h"
-#include "common.h"
-#include "board-flash.h"
-
-#define REG_FPGA_REV 0x10
-#define REG_FPGA_DIP_SWITCH_INPUT2 0x60
-#define MAX_SUPPORTED_GPMC_CONFIG 3
-
-#define DEBUG_BASE 0x08000000 /* debug board */
-
-/* various memory sizes */
-#define FLASH_SIZE_SDPV1 SZ_64M /* NOR flash (64 Meg aligned) */
-#define FLASH_SIZE_SDPV2 SZ_128M /* NOR flash (256 Meg aligned) */
-
-static struct physmap_flash_data board_nor_data = {
- .width = 2,
-};
-
-static struct resource board_nor_resource = {
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device board_nor_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &board_nor_data,
- },
- .num_resources = 1,
- .resource = &board_nor_resource,
-};
-
-static void
-__init board_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
-{
- int err;
-
- board_nor_data.parts = nor_parts;
- board_nor_data.nr_parts = nr_parts;
-
- /* Configure start address and size of NOR device */
- if (omap_rev() >= OMAP3430_REV_ES1_0) {
- err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1,
- (unsigned long *)&board_nor_resource.start);
- board_nor_resource.end = board_nor_resource.start
- + FLASH_SIZE_SDPV2 - 1;
- } else {
- err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1,
- (unsigned long *)&board_nor_resource.start);
- board_nor_resource.end = board_nor_resource.start
- + FLASH_SIZE_SDPV1 - 1;
- }
- if (err < 0) {
- pr_err("NOR: Can't request GPMC CS\n");
- return;
- }
- if (platform_device_register(&board_nor_device) < 0)
- pr_err("Unable to register NOR device\n");
-}
-
-#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
-static struct omap_onenand_platform_data board_onenand_data = {
- .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
-};
-
-void
-__init board_onenand_init(struct mtd_partition *onenand_parts,
- u8 nr_parts, u8 cs)
-{
- board_onenand_data.cs = cs;
- board_onenand_data.parts = onenand_parts;
- board_onenand_data.nr_parts = nr_parts;
-
- gpmc_onenand_init(&board_onenand_data);
-}
-#endif /* IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2) */
-
-#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
-
-/* Note that all values in this struct are in nanoseconds */
-struct gpmc_timings nand_default_timings[1] = {
- {
- .sync_clk = 0,
-
- .cs_on = 0,
- .cs_rd_off = 36,
- .cs_wr_off = 36,
-
- .we_on = 6,
- .oe_on = 6,
-
- .adv_on = 6,
- .adv_rd_off = 24,
- .adv_wr_off = 36,
-
- .we_off = 30,
- .oe_off = 48,
-
- .access = 54,
- .rd_cycle = 72,
- .wr_cycle = 72,
-
- .wr_access = 30,
- .wr_data_mux_bus = 0,
- },
-};
-
-static struct omap_nand_platform_data board_nand_data;
-
-void
-__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
- int nand_type, struct gpmc_timings *gpmc_t)
-{
- board_nand_data.cs = cs;
- board_nand_data.parts = nand_parts;
- board_nand_data.nr_parts = nr_parts;
- board_nand_data.devsize = nand_type;
-
- board_nand_data.ecc_opt = OMAP_ECC_HAM1_CODE_SW;
- gpmc_nand_init(&board_nand_data, gpmc_t);
-}
-#endif /* IS_ENABLED(CONFIG_MTD_NAND_OMAP2) */
-
-/**
- * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get
- * the various cs values.
- */
-static u8 get_gpmc0_type(void)
-{
- u8 cs = 0;
- void __iomem *fpga_map_addr;
-
- fpga_map_addr = ioremap(DEBUG_BASE, 4096);
- if (!fpga_map_addr)
- return -ENOMEM;
-
- if (!(readw_relaxed(fpga_map_addr + REG_FPGA_REV)))
- /* we dont have an DEBUG FPGA??? */
- /* Depend on #defines!! default to strata boot return param */
- goto unmap;
-
- /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */
- cs = readw_relaxed(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf;
-
- /* ES2.0 SDP's onwards 4 dip switches are provided for CS */
- if (omap_rev() >= OMAP3430_REV_ES1_0)
- /* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */
- cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) |
- ((cs & 2) << 1) | ((cs & 1) << 3);
- else
- /* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */
- cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2);
-unmap:
- iounmap(fpga_map_addr);
- return cs;
-}
-
-/**
- * board_flash_init - Identify devices connected to GPMC and register.
- *
- * @return - void.
- */
-void __init board_flash_init(struct flash_partitions partition_info[],
- char chip_sel_board[][GPMC_CS_NUM], int nand_type)
-{
- u8 cs = 0;
- u8 norcs = GPMC_CS_NUM + 1;
- u8 nandcs = GPMC_CS_NUM + 1;
- u8 onenandcs = GPMC_CS_NUM + 1;
- u8 idx;
- unsigned char *config_sel = NULL;
-
- /* REVISIT: Is this return correct idx for 2430 SDP?
- * for which cs configuration matches for 2430 SDP?
- */
- idx = get_gpmc0_type();
- if (idx >= MAX_SUPPORTED_GPMC_CONFIG) {
- pr_err("%s: Invalid chip select: %d\n", __func__, cs);
- return;
- }
- config_sel = (unsigned char *)(chip_sel_board[idx]);
-
- while (cs < GPMC_CS_NUM) {
- switch (config_sel[cs]) {
- case PDC_NOR:
- if (norcs > GPMC_CS_NUM)
- norcs = cs;
- break;
- case PDC_NAND:
- if (nandcs > GPMC_CS_NUM)
- nandcs = cs;
- break;
- case PDC_ONENAND:
- if (onenandcs > GPMC_CS_NUM)
- onenandcs = cs;
- break;
- }
- cs++;
- }
-
- if (norcs > GPMC_CS_NUM)
- pr_err("NOR: Unable to find configuration in GPMC\n");
- else
- board_nor_init(partition_info[0].parts,
- partition_info[0].nr_parts, norcs);
-
- if (onenandcs > GPMC_CS_NUM)
- pr_err("OneNAND: Unable to find configuration in GPMC\n");
- else
- board_onenand_init(partition_info[1].parts,
- partition_info[1].nr_parts, onenandcs);
-
- if (nandcs > GPMC_CS_NUM)
- pr_err("NAND: Unable to find configuration in GPMC\n");
- else
- board_nand_init(partition_info[2].parts,
- partition_info[2].nr_parts, nandcs,
- nand_type, nand_default_timings);
-}
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
deleted file mode 100644
index 8b39eec07318..000000000000
--- a/arch/arm/mach-omap2/board-flash.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * board-sdp.h
- *
- * Information structures for SDP-specific board config data
- *
- * Copyright (C) 2009 Nokia Corporation
- * Copyright (C) 2009 Texas Instruments
- *
- * 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/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define PDC_NOR 1
-#define PDC_NAND 2
-#define PDC_ONENAND 3
-#define DBG_MPDB 4
-
-struct flash_partitions {
- struct mtd_partition *parts;
- int nr_parts;
-};
-
-#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2) || IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
-extern void board_flash_init(struct flash_partitions [],
- char chip_sel[][GPMC_CS_NUM], int nand_type);
-#else
-static inline void board_flash_init(struct flash_partitions part[],
- char chip_sel[][GPMC_CS_NUM], int nand_type)
-{
-}
-#endif
-
-#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
-extern void board_nand_init(struct mtd_partition *nand_parts,
- u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t);
-extern struct gpmc_timings nand_default_timings[];
-#else
-static inline void board_nand_init(struct mtd_partition *nand_parts,
- u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t)
-{
-}
-#define nand_default_timings NULL
-#endif
-
-#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
-extern void board_onenand_init(struct mtd_partition *nand_parts,
- u8 nr_parts, u8 cs);
-#else
-static inline void board_onenand_init(struct mtd_partition *nand_parts,
- u8 nr_parts, u8 cs)
-{
-}
-#endif
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index bab814d2f37d..36d9943205ca 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -30,8 +30,6 @@ static const struct of_device_id omap_dt_match_table[] __initconst = {
static void __init omap_generic_init(void)
{
- omapdss_early_init_of();
-
pdata_quirks_init(omap_dt_match_table);
omapdss_init_of();
@@ -341,6 +339,7 @@ static const char *const dra72x_boards_compat[] __initconst = {
"ti,am5718",
"ti,am5716",
"ti,dra722",
+ "ti,dra718",
NULL,
};
diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c
index ef9ed36e8a61..6c679659cda5 100644
--- a/arch/arm/mach-omap2/clockdomains7xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains7xx_data.c
@@ -409,7 +409,7 @@ static struct clockdomain l4sec_7xx_clkdm = {
.dep_bit = DRA7XX_L4SEC_STATDEP_SHIFT,
.wkdep_srcs = l4sec_wkup_sleep_deps,
.sleepdep_srcs = l4sec_wkup_sleep_deps,
- .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .flags = CLKDM_CAN_SWSUP,
};
static struct clockdomain l3main1_7xx_clkdm = {
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
deleted file mode 100644
index 5388fcd3de72..000000000000
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * common-board-devices.c
- *
- * Copyright (C) 2011 CompuLab, Ltd.
- * Author: Mike Rapoport <mike@compulab.co.il>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
-
-#include <linux/platform_data/spi-omap2-mcspi.h>
-
-#include "common.h"
-#include "common-board-devices.h"
-
-#if IS_ENABLED(CONFIG_TOUCHSCREEN_ADS7846)
-static struct omap2_mcspi_device_config ads7846_mcspi_config = {
- .turbo_mode = 0,
-};
-
-static struct ads7846_platform_data ads7846_config = {
- .x_max = 0x0fff,
- .y_max = 0x0fff,
- .x_plate_ohms = 180,
- .pressure_max = 255,
- .debounce_max = 10,
- .debounce_tol = 3,
- .debounce_rep = 1,
- .gpio_pendown = -EINVAL,
- .keep_vref_on = 1,
-};
-
-static struct spi_board_info ads7846_spi_board_info __initdata = {
- .modalias = "ads7846",
- .bus_num = -EINVAL,
- .chip_select = 0,
- .max_speed_hz = 1500000,
- .controller_data = &ads7846_mcspi_config,
- .irq = -EINVAL,
- .platform_data = &ads7846_config,
-};
-
-void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
- struct ads7846_platform_data *board_pdata)
-{
- struct spi_board_info *spi_bi = &ads7846_spi_board_info;
- int err;
-
- /*
- * If a board defines get_pendown_state() function, request the pendown
- * GPIO and set the GPIO debounce time.
- * If a board does not define the get_pendown_state() function, then
- * the ads7846 driver will setup the pendown GPIO itself.
- */
- if (board_pdata && board_pdata->get_pendown_state) {
- err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
- if (err) {
- pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
- return;
- }
-
- if (gpio_debounce)
- gpio_set_debounce(gpio_pendown, gpio_debounce);
-
- gpio_export(gpio_pendown, 0);
- }
-
- spi_bi->bus_num = bus_num;
- spi_bi->irq = gpio_to_irq(gpio_pendown);
-
- ads7846_config.gpio_pendown = gpio_pendown;
-
- if (board_pdata) {
- board_pdata->gpio_pendown = gpio_pendown;
- board_pdata->gpio_pendown_debounce = gpio_debounce;
- spi_bi->platform_data = board_pdata;
- }
-
- spi_register_board_info(&ads7846_spi_board_info, 1);
-}
-#else
-void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
- struct ads7846_platform_data *board_pdata)
-{
-}
-#endif
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
index 07c88ae083fb..335c7822fea1 100644
--- a/arch/arm/mach-omap2/common-board-devices.h
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -3,15 +3,7 @@
#include <sound/tlv320aic3x.h>
#include <linux/mfd/menelaus.h>
-#include "twl-common.h"
-#define NAND_BLOCK_SIZE SZ_128K
-
-struct mtd_partition;
-struct ads7846_platform_data;
-
-void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
- struct ads7846_platform_data *board_pdata);
void *n8x0_legacy_init(void);
extern struct menelaus_platform_data n8x0_menelaus_platform_data;
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index deed42e1dd9c..c4f2ace91ea2 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -77,15 +77,6 @@ static inline int omap4_pm_init_early(void)
}
#endif
-#ifdef CONFIG_OMAP_MUX
-int omap_mux_late_init(void);
-#else
-static inline int omap_mux_late_init(void)
-{
- return 0;
-}
-#endif
-
extern void omap2_init_common_infrastructure(void);
extern void omap_init_time(void);
@@ -262,8 +253,6 @@ extern void __iomem *omap4_get_sar_ram_base(void);
extern void omap4_mpuss_early_init(void);
extern void omap_do_wfi(void);
-extern void omap4_secondary_startup(void);
-extern void omap4460_secondary_startup(void);
#ifdef CONFIG_SMP
/* Needed for secondary core boot */
@@ -275,16 +264,11 @@ extern void omap4_cpu_die(unsigned int cpu);
extern int omap4_cpu_kill(unsigned int cpu);
extern const struct smp_operations omap4_smp_ops;
-
-extern void omap5_secondary_startup(void);
-extern void omap5_secondary_hyp_startup(void);
#endif
#if defined(CONFIG_SMP) && defined(CONFIG_PM)
extern int omap4_mpuss_init(void);
extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
-extern int omap4_finish_suspend(unsigned long cpu_state);
-extern void omap4_cpu_resume(void);
extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
#else
static inline int omap4_enter_lowpower(unsigned int cpu,
@@ -305,14 +289,41 @@ static inline int omap4_mpuss_init(void)
return 0;
}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void omap4_secondary_startup(void);
+void omap4460_secondary_startup(void);
+int omap4_finish_suspend(unsigned long cpu_state);
+void omap4_cpu_resume(void);
+#else
+static inline void omap4_secondary_startup(void)
+{
+}
+
+static inline void omap4460_secondary_startup(void)
+{
+}
static inline int omap4_finish_suspend(unsigned long cpu_state)
{
return 0;
}
-
static inline void omap4_cpu_resume(void)
-{}
+{
+}
+#endif
+#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+void omap5_secondary_startup(void);
+void omap5_secondary_hyp_startup(void);
+#else
+static inline void omap5_secondary_startup(void)
+{
+}
+
+static inline void omap5_secondary_hyp_startup(void)
+{
+}
#endif
void pdata_quirks_init(const struct of_device_id *);
@@ -332,7 +343,6 @@ extern int omap_dss_reset(struct omap_hwmod *);
int omap_clk_init(void);
int __init omapdss_init_of(void);
-void __init omapdss_early_init_of(void);
#endif /* __ASSEMBLER__ */
#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index fa138d4032b6..a8b291f00109 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -21,6 +21,7 @@
#include "common.h"
#include "pm.h"
#include "prm.h"
+#include "soc.h"
#include "clockdomain.h"
#define MAX_CPUS 2
@@ -30,6 +31,7 @@ struct idle_statedata {
u32 cpu_state;
u32 mpu_logic_state;
u32 mpu_state;
+ u32 mpu_state_vote;
};
static struct idle_statedata omap4_idle_data[] = {
@@ -50,12 +52,26 @@ static struct idle_statedata omap4_idle_data[] = {
},
};
+static struct idle_statedata omap5_idle_data[] = {
+ {
+ .cpu_state = PWRDM_POWER_ON,
+ .mpu_state = PWRDM_POWER_ON,
+ .mpu_logic_state = PWRDM_POWER_ON,
+ },
+ {
+ .cpu_state = PWRDM_POWER_RET,
+ .mpu_state = PWRDM_POWER_RET,
+ .mpu_logic_state = PWRDM_POWER_RET,
+ },
+};
+
static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS];
static struct clockdomain *cpu_clkdm[MAX_CPUS];
static atomic_t abort_barrier;
static bool cpu_done[MAX_CPUS];
static struct idle_statedata *state_ptr = &omap4_idle_data[0];
+static DEFINE_RAW_SPINLOCK(mpu_lock);
/* Private functions */
@@ -77,6 +93,32 @@ static int omap_enter_idle_simple(struct cpuidle_device *dev,
return index;
}
+static int omap_enter_idle_smp(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ struct idle_statedata *cx = state_ptr + index;
+ unsigned long flag;
+
+ raw_spin_lock_irqsave(&mpu_lock, flag);
+ cx->mpu_state_vote++;
+ if (cx->mpu_state_vote == num_online_cpus()) {
+ pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+ omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+ }
+ raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+ omap4_enter_lowpower(dev->cpu, cx->cpu_state);
+
+ raw_spin_lock_irqsave(&mpu_lock, flag);
+ if (cx->mpu_state_vote == num_online_cpus())
+ omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
+ cx->mpu_state_vote--;
+ raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+ return index;
+}
+
static int omap_enter_idle_coupled(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
@@ -220,6 +262,32 @@ static struct cpuidle_driver omap4_idle_driver = {
.safe_state_index = 0,
};
+static struct cpuidle_driver omap5_idle_driver = {
+ .name = "omap5_idle",
+ .owner = THIS_MODULE,
+ .states = {
+ {
+ /* C1 - CPU0 ON + CPU1 ON + MPU ON */
+ .exit_latency = 2 + 2,
+ .target_residency = 5,
+ .enter = omap_enter_idle_simple,
+ .name = "C1",
+ .desc = "CPUx WFI, MPUSS ON"
+ },
+ {
+ /* C2 - CPU0 RET + CPU1 RET + MPU CSWR */
+ .exit_latency = 48 + 60,
+ .target_residency = 100,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = omap_enter_idle_smp,
+ .name = "C2",
+ .desc = "CPUx CSWR, MPUSS CSWR",
+ },
+ },
+ .state_count = ARRAY_SIZE(omap5_idle_data),
+ .safe_state_index = 0,
+};
+
/* Public functions */
/**
@@ -230,6 +298,16 @@ static struct cpuidle_driver omap4_idle_driver = {
*/
int __init omap4_idle_init(void)
{
+ struct cpuidle_driver *idle_driver;
+
+ if (soc_is_omap54xx()) {
+ state_ptr = &omap5_idle_data[0];
+ idle_driver = &omap5_idle_driver;
+ } else {
+ state_ptr = &omap4_idle_data[0];
+ idle_driver = &omap4_idle_driver;
+ }
+
mpu_pd = pwrdm_lookup("mpu_pwrdm");
cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
@@ -244,5 +322,5 @@ int __init omap4_idle_init(void)
/* Configure the broadcast timer on each cpu */
on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
- return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
+ return cpuidle_register(idle_driver, cpu_online_mask);
}
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 60a20f3b44de..3fdb94599184 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -30,7 +30,6 @@
#include "soc.h"
#include "common.h"
-#include "mux.h"
#include "control.h"
#include "display.h"
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 70b3eaf085e4..e71cca0950e9 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -565,11 +565,6 @@ int omap_dss_reset(struct omap_hwmod *oh)
return r;
}
-void __init omapdss_early_init_of(void)
-{
-
-}
-
static const char * const omapdss_compat_names[] __initconst = {
"ti,omap2-dss",
"ti,omap3-dss",
diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c
deleted file mode 100644
index 1d583bc0b1a9..000000000000
--- a/arch/arm/mach-omap2/dss-common.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 Texas Instruments, Inc..
- * Author: Tomi Valkeinen <tomi.valkeinen@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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * NOTE: this is a transitional file to help with DT adaptation.
- * This file will be removed when DSS supports DT.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-
-#include <linux/platform_data/omapdss.h>
-#include <video/omap-panel-data.h>
-
-#include "soc.h"
-#include "dss-common.h"
-#include "mux.h"
-#include "display.h"
-
diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h
deleted file mode 100644
index a9becf0d5be8..000000000000
--- a/arch/arm/mach-omap2/dss-common.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __OMAP_DSS_COMMON__
-#define __OMAP_DSS_COMMON__
-
-/*
- * NOTE: this is a transitional file to help with DT adaptation.
- * This file will be removed when DSS supports DT.
- */
-
-void __init omap4_panda_display_init_of(void);
-void __init omap_4430sdp_display_init_of(void);
-void __init omap3_igep2_display_init_of(void);
-
-#endif
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
deleted file mode 100644
index 2757504a13c4..000000000000
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/gpmc-smsc911x.c
- *
- * Copyright (C) 2009 Li-Pro.Net
- * Stephan Linz <linz@li-pro.net>
- *
- * Modified from linux/arch/arm/mach-omap2/gpmc-smc91x.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.
- */
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/smsc911x.h>
-
-#include "gpmc.h"
-#include "gpmc-smsc911x.h"
-
-static struct resource gpmc_smsc911x_resources[] = {
- [0] = {
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
- },
-};
-
-static struct smsc911x_platform_config gpmc_smsc911x_config = {
- .phy_interface = PHY_INTERFACE_MODE_MII,
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-};
-
-/*
- * Initialize smsc911x device connected to the GPMC. Note that we
- * assume that pin multiplexing is done in the board-*.c file,
- * or in the bootloader.
- */
-void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg)
-{
- struct platform_device *pdev;
- unsigned long cs_mem_base;
- int ret;
-
- if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
- pr_err("Failed to request GPMC mem region\n");
- return;
- }
-
- gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
- gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
-
- if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "smsc911x irq")) {
- pr_err("Failed to request IRQ GPIO%d\n", gpmc_cfg->gpio_irq);
- goto free1;
- }
-
- gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
-
- if (gpio_is_valid(gpmc_cfg->gpio_reset)) {
- ret = gpio_request_one(gpmc_cfg->gpio_reset,
- GPIOF_OUT_INIT_HIGH, "smsc911x reset");
- if (ret) {
- pr_err("Failed to request reset GPIO%d\n",
- gpmc_cfg->gpio_reset);
- goto free2;
- }
-
- gpio_set_value(gpmc_cfg->gpio_reset, 0);
- msleep(100);
- gpio_set_value(gpmc_cfg->gpio_reset, 1);
- }
-
- gpmc_smsc911x_config.flags = gpmc_cfg->flags ? : SMSC911X_USE_16BIT;
-
- pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id,
- gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources),
- &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config));
- if (IS_ERR(pdev)) {
- pr_err("Unable to register platform device\n");
- gpio_free(gpmc_cfg->gpio_reset);
- goto free2;
- }
-
- return;
-
-free2:
- gpio_free(gpmc_cfg->gpio_irq);
-free1:
- gpmc_cs_free(gpmc_cfg->cs);
-
- pr_err("Could not initialize smsc911x device\n");
-}
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.h b/arch/arm/mach-omap2/gpmc-smsc911x.h
deleted file mode 100644
index 99a05b8412fa..000000000000
--- a/arch/arm/mach-omap2/gpmc-smsc911x.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
- *
- * Copyright (C) 2009 Li-Pro.Net
- * Stephan Linz <linz@li-pro.net>
- *
- * Modified from arch/arm/plat-omap/include/plat/gpmc-smc91x.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_OMAP_GPMC_SMSC911X_H__
-
-struct omap_smsc911x_platform_data {
- int id;
- int cs;
- int gpio_irq;
- int gpio_reset;
- u32 flags;
-};
-
-#if IS_ENABLED(CONFIG_SMSC911X)
-
-extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
-
-#else
-
-static inline void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
-{
-}
-
-#endif
-#endif
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 478097741bce..cb754c46747e 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -22,7 +22,6 @@
#include "omap_device.h"
#include "omap-pm.h"
-#include "mux.h"
#include "hsmmc.h"
#include "control.h"
@@ -147,91 +146,6 @@ static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
return 0;
}
-static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
- *mmc_controller, int controller_nr)
-{
- if (gpio_is_valid(mmc_controller->gpio_cd) &&
- (mmc_controller->gpio_cd < OMAP_MAX_GPIO_LINES))
- omap_mux_init_gpio(mmc_controller->gpio_cd,
- OMAP_PIN_INPUT_PULLUP);
- if (gpio_is_valid(mmc_controller->gpio_cod) &&
- (mmc_controller->gpio_cod < OMAP_MAX_GPIO_LINES))
- omap_mux_init_gpio(mmc_controller->gpio_cod,
- OMAP_PIN_INPUT_PULLUP);
- if (gpio_is_valid(mmc_controller->gpio_wp) &&
- (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES))
- omap_mux_init_gpio(mmc_controller->gpio_wp,
- OMAP_PIN_INPUT_PULLUP);
- if (cpu_is_omap34xx()) {
- if (controller_nr == 0) {
- omap_mux_init_signal("sdmmc1_clk",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_cmd",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_dat0",
- OMAP_PIN_INPUT_PULLUP);
- if (mmc_controller->caps &
- (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
- omap_mux_init_signal("sdmmc1_dat1",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_dat2",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_dat3",
- OMAP_PIN_INPUT_PULLUP);
- }
- if (mmc_controller->caps &
- MMC_CAP_8_BIT_DATA) {
- omap_mux_init_signal("sdmmc1_dat4",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_dat5",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_dat6",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc1_dat7",
- OMAP_PIN_INPUT_PULLUP);
- }
- }
- if (controller_nr == 1) {
- /* MMC2 */
- omap_mux_init_signal("sdmmc2_clk",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_cmd",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_dat0",
- OMAP_PIN_INPUT_PULLUP);
-
- /*
- * For 8 wire configurations, Lines DAT4, 5, 6 and 7
- * need to be muxed in the board-*.c files
- */
- if (mmc_controller->caps &
- (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
- omap_mux_init_signal("sdmmc2_dat1",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_dat2",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_dat3",
- OMAP_PIN_INPUT_PULLUP);
- }
- if (mmc_controller->caps &
- MMC_CAP_8_BIT_DATA) {
- omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
- OMAP_PIN_INPUT_PULLUP);
- }
- }
-
- /*
- * For MMC3 the pins need to be muxed in the board-*.c files
- */
- }
-}
-
static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
struct omap_hsmmc_platform_data *mmc)
{
@@ -410,8 +324,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
if (res < 0)
goto free_mmc;
- omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
-
name = "omap_hsmmc";
res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
"mmc%d", ctrl_nr);
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
index b9d8e47ffe8e..91a21c3923b2 100644
--- a/arch/arm/mach-omap2/i2c.c
+++ b/arch/arm/mach-omap2/i2c.c
@@ -26,7 +26,6 @@
#include "prm.h"
#include "common.h"
-#include "mux.h"
#include "i2c.h"
/* In register I2C_CON, Bit 15 is the I2C enable bit */
@@ -36,20 +35,6 @@
#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
-static void __init omap2_i2c_mux_pins(int bus_id)
-{
- char mux_name[sizeof("i2c2_scl.i2c2_scl")];
-
- /* First I2C bus is not muxable */
- if (bus_id == 1)
- return;
-
- sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id);
- omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
- sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
- omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
-}
-
/**
* omap_i2c_reset - reset the omap i2c module.
* @oh: struct omap_hwmod *
@@ -107,85 +92,3 @@ int omap_i2c_reset(struct omap_hwmod *oh)
return 0;
}
-
-static int __init omap_i2c_nr_ports(void)
-{
- int ports = 0;
-
- if (cpu_is_omap24xx())
- ports = 2;
- else if (cpu_is_omap34xx())
- ports = 3;
- else if (cpu_is_omap44xx())
- ports = 4;
- return ports;
-}
-
-/*
- * XXX This function is a temporary compatibility wrapper - only
- * needed until the I2C driver can be converted to call
- * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
- */
-static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
-{
- omap_pm_set_max_mpu_wakeup_lat(dev, t);
-}
-
-static const char name[] = "omap_i2c";
-
-int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata,
- int bus_id)
-{
- int l;
- struct omap_hwmod *oh;
- struct platform_device *pdev;
- char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
- struct omap_i2c_bus_platform_data *pdata;
- struct omap_i2c_dev_attr *dev_attr;
-
- if (bus_id > omap_i2c_nr_ports())
- return -EINVAL;
-
- omap2_i2c_mux_pins(bus_id);
-
- l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
- WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
- "String buffer overflow in I2C%d device setup\n", bus_id);
- oh = omap_hwmod_lookup(oh_name);
- if (!oh) {
- pr_err("Could not look up %s\n", oh_name);
- return -EEXIST;
- }
-
- pdata = i2c_pdata;
- /*
- * pass the hwmod class's CPU-specific knowledge of I2C IP revision in
- * use, and functionality implementation flags, up to the OMAP I2C
- * driver via platform data
- */
- pdata->rev = oh->class->rev;
-
- dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
- pdata->flags = dev_attr->flags;
-
- /*
- * When waiting for completion of a i2c transfer, we need to
- * set a wake up latency constraint for the MPU. This is to
- * ensure quick enough wakeup from idle, when transfer
- * completes.
- * Only omap3 has support for constraints
- */
- if (cpu_is_omap34xx())
- pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
- pdev = omap_device_build(name, bus_id, oh, pdata,
- sizeof(struct omap_i2c_bus_platform_data));
- WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
-
- return PTR_ERR_OR_ZERO(pdev);
-}
-
-static int __init omap_i2c_cmdline(void)
-{
- return omap_register_i2c_bus_cmdline();
-}
-omap_subsys_initcall(omap_i2c_cmdline);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 0e9acdd95d70..5aafb8449c40 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -427,7 +427,6 @@ static void __init omap_hwmod_init_postsetup(void)
static void __init __maybe_unused omap_common_late_init(void)
{
- omap_mux_late_init();
omap2_common_pm_late_init();
omap_soc_device_init();
}
@@ -717,10 +716,11 @@ void __init omap5_init_early(void)
OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
omap2_control_base_init();
- omap4_pm_init_early();
omap2_prcm_base_init();
omap5xxx_check_revision();
omap4_sar_ram_init();
+ omap4_mpuss_early_init();
+ omap4_pm_init_early();
omap54xx_voltagedomains_init();
omap54xx_powerdomains_init();
omap54xx_clockdomains_init();
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
index 8bdf182422bd..5a3bc3de58d0 100644
--- a/arch/arm/mach-omap2/msdi.c
+++ b/arch/arm/mach-omap2/msdi.c
@@ -30,7 +30,6 @@
#include "control.h"
#include "omap_hwmod.h"
#include "omap_device.h"
-#include "mux.h"
#include "mmc.h"
/*
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
deleted file mode 100644
index 176eef6ef338..000000000000
--- a/arch/arm/mach-omap2/mux.c
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/mux.c
- *
- * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
- *
- * Copyright (C) 2004 - 2010 Texas Instruments Inc.
- * Copyright (C) 2003 - 2008 Nokia Corporation
- *
- * Written by Tony Lindgren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-
-
-#include "omap_hwmod.h"
-
-#include "soc.h"
-#include "control.h"
-#include "mux.h"
-#include "prm.h"
-#include "common.h"
-
-#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
-#define OMAP_MUX_BASE_SZ 0x5ca
-
-struct omap_mux_entry {
- struct omap_mux mux;
- struct list_head node;
-};
-
-static LIST_HEAD(mux_partitions);
-static DEFINE_MUTEX(muxmode_mutex);
-
-struct omap_mux_partition *omap_mux_get(const char *name)
-{
- struct omap_mux_partition *partition;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- if (!strcmp(name, partition->name))
- return partition;
- }
-
- return NULL;
-}
-
-u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
-{
- if (partition->flags & OMAP_MUX_REG_8BIT)
- return readb_relaxed(partition->base + reg);
- else
- return readw_relaxed(partition->base + reg);
-}
-
-void omap_mux_write(struct omap_mux_partition *partition, u16 val,
- u16 reg)
-{
- if (partition->flags & OMAP_MUX_REG_8BIT)
- writeb_relaxed(val, partition->base + reg);
- else
- writew_relaxed(val, partition->base + reg);
-}
-
-void omap_mux_write_array(struct omap_mux_partition *partition,
- struct omap_board_mux *board_mux)
-{
- if (!board_mux)
- return;
-
- while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
- omap_mux_write(partition, board_mux->value,
- board_mux->reg_offset);
- board_mux++;
- }
-}
-
-#ifdef CONFIG_OMAP_MUX
-
-static char *omap_mux_options;
-
-static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
- int gpio, int val)
-{
- struct omap_mux_entry *e;
- struct omap_mux *gpio_mux = NULL;
- u16 old_mode;
- u16 mux_mode;
- int found = 0;
- struct list_head *muxmodes = &partition->muxmodes;
-
- if (!gpio)
- return -EINVAL;
-
- list_for_each_entry(e, muxmodes, node) {
- struct omap_mux *m = &e->mux;
- if (gpio == m->gpio) {
- gpio_mux = m;
- found++;
- }
- }
-
- if (found == 0) {
- pr_err("%s: Could not set gpio%i\n", __func__, gpio);
- return -ENODEV;
- }
-
- if (found > 1) {
- pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
- found, gpio);
- return -EINVAL;
- }
-
- old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
- mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
- mux_mode |= partition->gpio;
- pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
- gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
- omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
-
- return 0;
-}
-
-int __init omap_mux_init_gpio(int gpio, int val)
-{
- struct omap_mux_partition *partition;
- int ret;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- ret = _omap_mux_init_gpio(partition, gpio, val);
- if (!ret)
- return ret;
- }
-
- return -ENODEV;
-}
-
-static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
- const char *muxname,
- struct omap_mux **found_mux)
-{
- struct omap_mux *mux = NULL;
- struct omap_mux_entry *e;
- const char *mode_name;
- int found = 0, found_mode = 0, mode0_len = 0;
- struct list_head *muxmodes = &partition->muxmodes;
-
- mode_name = strchr(muxname, '.');
- if (mode_name) {
- mode0_len = strlen(muxname) - strlen(mode_name);
- mode_name++;
- } else {
- mode_name = muxname;
- }
-
- list_for_each_entry(e, muxmodes, node) {
- char *m0_entry;
- int i;
-
- mux = &e->mux;
- m0_entry = mux->muxnames[0];
-
- /* First check for full name in mode0.muxmode format */
- if (mode0_len)
- if (strncmp(muxname, m0_entry, mode0_len) ||
- (strlen(m0_entry) != mode0_len))
- continue;
-
- /* Then check for muxmode only */
- for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
- char *mode_cur = mux->muxnames[i];
-
- if (!mode_cur)
- continue;
-
- if (!strcmp(mode_name, mode_cur)) {
- *found_mux = mux;
- found++;
- found_mode = i;
- }
- }
- }
-
- if (found == 1) {
- return found_mode;
- }
-
- if (found > 1) {
- pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
- found, muxname);
- return -EINVAL;
- }
-
- return -ENODEV;
-}
-
-int __init omap_mux_get_by_name(const char *muxname,
- struct omap_mux_partition **found_partition,
- struct omap_mux **found_mux)
-{
- struct omap_mux_partition *partition;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- struct omap_mux *mux = NULL;
- int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux);
- if (mux_mode < 0)
- continue;
-
- *found_partition = partition;
- *found_mux = mux;
-
- return mux_mode;
- }
-
- pr_err("%s: Could not find signal %s\n", __func__, muxname);
-
- return -ENODEV;
-}
-
-int __init omap_mux_init_signal(const char *muxname, int val)
-{
- struct omap_mux_partition *partition = NULL;
- struct omap_mux *mux = NULL;
- u16 old_mode;
- int mux_mode;
-
- mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
- if (mux_mode < 0 || !mux)
- return mux_mode;
-
- old_mode = omap_mux_read(partition, mux->reg_offset);
- mux_mode |= val;
- pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
- __func__, muxname, old_mode, mux_mode);
- omap_mux_write(partition, mux_mode, mux->reg_offset);
-
- return 0;
-}
-
-struct omap_hwmod_mux_info * __init
-omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
-{
- struct omap_hwmod_mux_info *hmux;
- int i, nr_pads_dynamic = 0;
-
- if (!bpads || nr_pads < 1)
- return NULL;
-
- hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
- if (!hmux)
- goto err1;
-
- hmux->nr_pads = nr_pads;
-
- hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
- nr_pads, GFP_KERNEL);
- if (!hmux->pads)
- goto err2;
-
- for (i = 0; i < hmux->nr_pads; i++) {
- struct omap_mux_partition *partition;
- struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
- struct omap_mux *mux;
- int mux_mode;
-
- mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
- if (mux_mode < 0)
- goto err3;
- if (!pad->partition)
- pad->partition = partition;
- if (!pad->mux)
- pad->mux = mux;
-
- pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
- if (!pad->name) {
- int j;
-
- for (j = i - 1; j >= 0; j--)
- kfree(hmux->pads[j].name);
- goto err3;
- }
- strcpy(pad->name, bpad->name);
-
- pad->flags = bpad->flags;
- pad->enable = bpad->enable;
- pad->idle = bpad->idle;
- pad->off = bpad->off;
-
- if (pad->flags &
- (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP))
- nr_pads_dynamic++;
-
- pr_debug("%s: Initialized %s\n", __func__, pad->name);
- }
-
- if (!nr_pads_dynamic)
- return hmux;
-
- /*
- * Add pads that need dynamic muxing into a separate list
- */
-
- hmux->nr_pads_dynamic = nr_pads_dynamic;
- hmux->pads_dynamic = kzalloc(sizeof(struct omap_device_pad *) *
- nr_pads_dynamic, GFP_KERNEL);
- if (!hmux->pads_dynamic) {
- pr_err("%s: Could not allocate dynamic pads\n", __func__);
- return hmux;
- }
-
- nr_pads_dynamic = 0;
- for (i = 0; i < hmux->nr_pads; i++) {
- struct omap_device_pad *pad = &hmux->pads[i];
-
- if (pad->flags &
- (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) {
- pr_debug("%s: pad %s tagged dynamic\n",
- __func__, pad->name);
- hmux->pads_dynamic[nr_pads_dynamic] = pad;
- nr_pads_dynamic++;
- }
- }
-
- return hmux;
-
-err3:
- kfree(hmux->pads);
-err2:
- kfree(hmux);
-err1:
- pr_err("%s: Could not allocate device mux entry\n", __func__);
-
- return NULL;
-}
-
-/**
- * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
- * @hmux: Pads for a hwmod
- * @mpu_irqs: MPU irq array for a hwmod
- *
- * Scans the wakeup status of pads for a single hwmod. If an irq
- * array is defined for this mux, the parser will call the registered
- * ISRs for corresponding pads, otherwise the parser will stop at the
- * first wakeup active pad and return. Returns true if there is a
- * pending and non-served wakeup event for the mux, otherwise false.
- */
-static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
- struct omap_hwmod_irq_info *mpu_irqs)
-{
- int i, irq;
- unsigned int val;
- u32 handled_irqs = 0;
-
- for (i = 0; i < hmux->nr_pads_dynamic; i++) {
- struct omap_device_pad *pad = hmux->pads_dynamic[i];
-
- if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) ||
- !(pad->idle & OMAP_WAKEUP_EN))
- continue;
-
- val = omap_mux_read(pad->partition, pad->mux->reg_offset);
- if (!(val & OMAP_WAKEUP_EVENT))
- continue;
-
- if (!hmux->irqs)
- return true;
-
- irq = hmux->irqs[i];
- /* make sure we only handle each irq once */
- if (handled_irqs & 1 << irq)
- continue;
-
- handled_irqs |= 1 << irq;
-
- generic_handle_irq(mpu_irqs[irq].irq);
- }
-
- return false;
-}
-
-/**
- * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
- *
- * Checks a single hwmod for every wakeup capable pad to see if there is an
- * active wakeup event. If this is the case, call the corresponding ISR.
- */
-static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
-{
- if (!oh->mux || !oh->mux->enabled)
- return 0;
- if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
- generic_handle_irq(oh->mpu_irqs[0].irq);
- return 0;
-}
-
-/**
- * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
- *
- * Calls a function for each registered omap_hwmod to check
- * pad wakeup statuses.
- */
-static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
-{
- omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
- return IRQ_HANDLED;
-}
-
-/* Assumes the calling function takes care of locking */
-void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
-{
- int i;
-
- /* Runtime idling of dynamic pads */
- if (state == _HWMOD_STATE_IDLE && hmux->enabled) {
- for (i = 0; i < hmux->nr_pads_dynamic; i++) {
- struct omap_device_pad *pad = hmux->pads_dynamic[i];
- int val = -EINVAL;
-
- val = pad->idle;
- omap_mux_write(pad->partition, val,
- pad->mux->reg_offset);
- }
-
- return;
- }
-
- /* Runtime enabling of dynamic pads */
- if ((state == _HWMOD_STATE_ENABLED) && hmux->pads_dynamic
- && hmux->enabled) {
- for (i = 0; i < hmux->nr_pads_dynamic; i++) {
- struct omap_device_pad *pad = hmux->pads_dynamic[i];
- int val = -EINVAL;
-
- val = pad->enable;
- omap_mux_write(pad->partition, val,
- pad->mux->reg_offset);
- }
-
- return;
- }
-
- /* Enabling or disabling of all pads */
- for (i = 0; i < hmux->nr_pads; i++) {
- struct omap_device_pad *pad = &hmux->pads[i];
- int flags, val = -EINVAL;
-
- flags = pad->flags;
-
- switch (state) {
- case _HWMOD_STATE_ENABLED:
- val = pad->enable;
- pr_debug("%s: Enabling %s %x\n", __func__,
- pad->name, val);
- break;
- case _HWMOD_STATE_DISABLED:
- /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */
- if (flags & OMAP_DEVICE_PAD_REMUX)
- val = pad->off;
- else
- val = OMAP_MUX_MODE7;
- pr_debug("%s: Disabling %s %x\n", __func__,
- pad->name, val);
- break;
- default:
- /* Nothing to be done */
- break;
- }
-
- if (val >= 0) {
- omap_mux_write(pad->partition, val,
- pad->mux->reg_offset);
- pad->flags = flags;
- }
- }
-
- if (state == _HWMOD_STATE_ENABLED)
- hmux->enabled = true;
- else
- hmux->enabled = false;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#define OMAP_MUX_MAX_NR_FLAGS 10
-#define OMAP_MUX_TEST_FLAG(val, mask) \
- if (((val) & (mask)) == (mask)) { \
- i++; \
- flags[i] = #mask; \
- }
-
-/* REVISIT: Add checking for non-optimal mux settings */
-static inline void omap_mux_decode(struct seq_file *s, u16 val)
-{
- char *flags[OMAP_MUX_MAX_NR_FLAGS];
- char mode[sizeof("OMAP_MUX_MODE") + 1];
- int i = -1;
-
- sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
- i++;
- flags[i] = mode;
-
- OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
- if (val & OMAP_OFF_EN) {
- if (!(val & OMAP_OFFOUT_EN)) {
- if (!(val & OMAP_OFF_PULL_UP)) {
- OMAP_MUX_TEST_FLAG(val,
- OMAP_PIN_OFF_INPUT_PULLDOWN);
- } else {
- OMAP_MUX_TEST_FLAG(val,
- OMAP_PIN_OFF_INPUT_PULLUP);
- }
- } else {
- if (!(val & OMAP_OFFOUT_VAL)) {
- OMAP_MUX_TEST_FLAG(val,
- OMAP_PIN_OFF_OUTPUT_LOW);
- } else {
- OMAP_MUX_TEST_FLAG(val,
- OMAP_PIN_OFF_OUTPUT_HIGH);
- }
- }
- }
-
- if (val & OMAP_INPUT_EN) {
- if (val & OMAP_PULL_ENA) {
- if (!(val & OMAP_PULL_UP)) {
- OMAP_MUX_TEST_FLAG(val,
- OMAP_PIN_INPUT_PULLDOWN);
- } else {
- OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
- }
- } else {
- OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
- }
- } else {
- i++;
- flags[i] = "OMAP_PIN_OUTPUT";
- }
-
- do {
- seq_printf(s, "%s", flags[i]);
- if (i > 0)
- seq_printf(s, " | ");
- } while (i-- > 0);
-}
-
-#define OMAP_MUX_DEFNAME_LEN 32
-
-static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
-{
- struct omap_mux_partition *partition = s->private;
- struct omap_mux_entry *e;
- u8 omap_gen = omap_rev() >> 28;
-
- list_for_each_entry(e, &partition->muxmodes, node) {
- struct omap_mux *m = &e->mux;
- char m0_def[OMAP_MUX_DEFNAME_LEN];
- char *m0_name = m->muxnames[0];
- u16 val;
- int i, mode;
-
- if (!m0_name)
- continue;
-
- /* REVISIT: Needs to be updated if mode0 names get longer */
- for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
- if (m0_name[i] == '\0') {
- m0_def[i] = m0_name[i];
- break;
- }
- m0_def[i] = toupper(m0_name[i]);
- }
- val = omap_mux_read(partition, m->reg_offset);
- mode = val & OMAP_MUX_MODE7;
- if (mode != 0)
- seq_printf(s, "/* %s */\n", m->muxnames[mode]);
-
- /*
- * XXX: Might be revisited to support differences across
- * same OMAP generation.
- */
- seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
- omap_mux_decode(s, val);
- seq_printf(s, "),\n");
- }
-
- return 0;
-}
-
-static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
-{
- return single_open(file, omap_mux_dbg_board_show, inode->i_private);
-}
-
-static const struct file_operations omap_mux_dbg_board_fops = {
- .open = omap_mux_dbg_board_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
-{
- struct omap_mux_partition *partition;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- struct list_head *muxmodes = &partition->muxmodes;
- struct omap_mux_entry *e;
-
- list_for_each_entry(e, muxmodes, node) {
- struct omap_mux *m = &e->mux;
-
- if (m == mux)
- return partition;
- }
- }
-
- return NULL;
-}
-
-static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
-{
- struct omap_mux *m = s->private;
- struct omap_mux_partition *partition;
- const char *none = "NA";
- u16 val;
- int mode;
-
- partition = omap_mux_get_partition(m);
- if (!partition)
- return 0;
-
- val = omap_mux_read(partition, m->reg_offset);
- mode = val & OMAP_MUX_MODE7;
-
- seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
- m->muxnames[0], m->muxnames[mode],
- partition->phys + m->reg_offset, m->reg_offset, val,
- m->balls[0] ? m->balls[0] : none,
- m->balls[1] ? m->balls[1] : none);
- seq_printf(s, "mode: ");
- omap_mux_decode(s, val);
- seq_printf(s, "\n");
- seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
- m->muxnames[0] ? m->muxnames[0] : none,
- m->muxnames[1] ? m->muxnames[1] : none,
- m->muxnames[2] ? m->muxnames[2] : none,
- m->muxnames[3] ? m->muxnames[3] : none,
- m->muxnames[4] ? m->muxnames[4] : none,
- m->muxnames[5] ? m->muxnames[5] : none,
- m->muxnames[6] ? m->muxnames[6] : none,
- m->muxnames[7] ? m->muxnames[7] : none);
-
- return 0;
-}
-
-#define OMAP_MUX_MAX_ARG_CHAR 7
-
-static ssize_t omap_mux_dbg_signal_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct seq_file *seqf;
- struct omap_mux *m;
- u16 val;
- int ret;
- struct omap_mux_partition *partition;
-
- if (count > OMAP_MUX_MAX_ARG_CHAR)
- return -EINVAL;
-
- ret = kstrtou16_from_user(user_buf, count, 0x10, &val);
- if (ret < 0)
- return ret;
-
- seqf = file->private_data;
- m = seqf->private;
-
- partition = omap_mux_get_partition(m);
- if (!partition)
- return -ENODEV;
-
- omap_mux_write(partition, val, m->reg_offset);
- *ppos += count;
-
- return count;
-}
-
-static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
-{
- return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
-}
-
-static const struct file_operations omap_mux_dbg_signal_fops = {
- .open = omap_mux_dbg_signal_open,
- .read = seq_read,
- .write = omap_mux_dbg_signal_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static struct dentry *mux_dbg_dir;
-
-static void __init omap_mux_dbg_create_entry(
- struct omap_mux_partition *partition,
- struct dentry *mux_dbg_dir)
-{
- struct omap_mux_entry *e;
-
- list_for_each_entry(e, &partition->muxmodes, node) {
- struct omap_mux *m = &e->mux;
-
- (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO,
- mux_dbg_dir, m,
- &omap_mux_dbg_signal_fops);
- }
-}
-
-static void __init omap_mux_dbg_init(void)
-{
- struct omap_mux_partition *partition;
- static struct dentry *mux_dbg_board_dir;
-
- mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
- if (!mux_dbg_dir)
- return;
-
- mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
- if (!mux_dbg_board_dir)
- return;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- omap_mux_dbg_create_entry(partition, mux_dbg_dir);
- (void)debugfs_create_file(partition->name, S_IRUGO,
- mux_dbg_board_dir, partition,
- &omap_mux_dbg_board_fops);
- }
-}
-
-#else
-static inline void omap_mux_dbg_init(void)
-{
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static void __init omap_mux_free_names(struct omap_mux *m)
-{
- int i;
-
- for (i = 0; i < OMAP_MUX_NR_MODES; i++)
- kfree(m->muxnames[i]);
-
-#ifdef CONFIG_DEBUG_FS
- for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
- kfree(m->balls[i]);
-#endif
-
-}
-
-/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
-int __init omap_mux_late_init(void)
-{
- struct omap_mux_partition *partition;
- int ret;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- struct omap_mux_entry *e, *tmp;
- list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
- struct omap_mux *m = &e->mux;
- u16 mode = omap_mux_read(partition, m->reg_offset);
-
- if (OMAP_MODE_GPIO(partition, mode))
- continue;
-
-#ifndef CONFIG_DEBUG_FS
- mutex_lock(&muxmode_mutex);
- list_del(&e->node);
- mutex_unlock(&muxmode_mutex);
- omap_mux_free_names(m);
- kfree(m);
-#endif
- }
- }
-
- omap_mux_dbg_init();
-
- /* see pinctrl-single-omap for the wake-up interrupt handling */
- if (of_have_populated_dt())
- return 0;
-
- ret = request_irq(omap_prcm_event_to_irq("io"),
- omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
- "hwmod_io", omap_mux_late_init);
-
- if (ret)
- pr_warn("mux: Failed to setup hwmod io irq %d\n", ret);
-
- return 0;
-}
-
-static void __init omap_mux_package_fixup(struct omap_mux *p,
- struct omap_mux *superset)
-{
- while (p->reg_offset != OMAP_MUX_TERMINATOR) {
- struct omap_mux *s = superset;
- int found = 0;
-
- while (s->reg_offset != OMAP_MUX_TERMINATOR) {
- if (s->reg_offset == p->reg_offset) {
- *s = *p;
- found++;
- break;
- }
- s++;
- }
- if (!found)
- pr_err("%s: Unknown entry offset 0x%x\n", __func__,
- p->reg_offset);
- p++;
- }
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static void __init omap_mux_package_init_balls(struct omap_ball *b,
- struct omap_mux *superset)
-{
- while (b->reg_offset != OMAP_MUX_TERMINATOR) {
- struct omap_mux *s = superset;
- int found = 0;
-
- while (s->reg_offset != OMAP_MUX_TERMINATOR) {
- if (s->reg_offset == b->reg_offset) {
- s->balls[0] = b->balls[0];
- s->balls[1] = b->balls[1];
- found++;
- break;
- }
- s++;
- }
- if (!found)
- pr_err("%s: Unknown ball offset 0x%x\n", __func__,
- b->reg_offset);
- b++;
- }
-}
-
-#else /* CONFIG_DEBUG_FS */
-
-static inline void omap_mux_package_init_balls(struct omap_ball *b,
- struct omap_mux *superset)
-{
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-static int __init omap_mux_setup(char *options)
-{
- if (!options)
- return 0;
-
- omap_mux_options = options;
-
- return 1;
-}
-__setup("omap_mux=", omap_mux_setup);
-
-/*
- * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
- * cmdline options only override the bootloader values.
- * During development, please enable CONFIG_DEBUG_FS, and use the
- * signal specific entries under debugfs.
- */
-static void __init omap_mux_set_cmdline_signals(void)
-{
- char *options, *next_opt, *token;
-
- if (!omap_mux_options)
- return;
-
- options = kstrdup(omap_mux_options, GFP_KERNEL);
- if (!options)
- return;
-
- next_opt = options;
-
- while ((token = strsep(&next_opt, ",")) != NULL) {
- char *keyval, *name;
- u16 val;
-
- keyval = token;
- name = strsep(&keyval, "=");
- if (name) {
- int res;
-
- res = kstrtou16(keyval, 0x10, &val);
- if (res < 0)
- continue;
-
- omap_mux_init_signal(name, (u16)val);
- }
- }
-
- kfree(options);
-}
-
-static int __init omap_mux_copy_names(struct omap_mux *src,
- struct omap_mux *dst)
-{
- int i;
-
- for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
- if (src->muxnames[i]) {
- dst->muxnames[i] = kstrdup(src->muxnames[i],
- GFP_KERNEL);
- if (!dst->muxnames[i])
- goto free;
- }
- }
-
-#ifdef CONFIG_DEBUG_FS
- for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
- if (src->balls[i]) {
- dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL);
- if (!dst->balls[i])
- goto free;
- }
- }
-#endif
-
- return 0;
-
-free:
- omap_mux_free_names(dst);
- return -ENOMEM;
-
-}
-
-#endif /* CONFIG_OMAP_MUX */
-
-static struct omap_mux *omap_mux_get_by_gpio(
- struct omap_mux_partition *partition,
- int gpio)
-{
- struct omap_mux_entry *e;
- struct omap_mux *ret = NULL;
-
- list_for_each_entry(e, &partition->muxmodes, node) {
- struct omap_mux *m = &e->mux;
- if (m->gpio == gpio) {
- ret = m;
- break;
- }
- }
-
- return ret;
-}
-
-/* Needed for dynamic muxing of GPIO pins for off-idle */
-u16 omap_mux_get_gpio(int gpio)
-{
- struct omap_mux_partition *partition;
- struct omap_mux *m = NULL;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- m = omap_mux_get_by_gpio(partition, gpio);
- if (m)
- return omap_mux_read(partition, m->reg_offset);
- }
-
- if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
- pr_err("%s: Could not get gpio%i\n", __func__, gpio);
-
- return OMAP_MUX_TERMINATOR;
-}
-
-/* Needed for dynamic muxing of GPIO pins for off-idle */
-void omap_mux_set_gpio(u16 val, int gpio)
-{
- struct omap_mux_partition *partition;
- struct omap_mux *m = NULL;
-
- list_for_each_entry(partition, &mux_partitions, node) {
- m = omap_mux_get_by_gpio(partition, gpio);
- if (m) {
- omap_mux_write(partition, val, m->reg_offset);
- return;
- }
- }
-
- if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
- pr_err("%s: Could not set gpio%i\n", __func__, gpio);
-}
-
-static struct omap_mux * __init omap_mux_list_add(
- struct omap_mux_partition *partition,
- struct omap_mux *src)
-{
- struct omap_mux_entry *entry;
- struct omap_mux *m;
-
- entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
- if (!entry)
- return NULL;
-
- m = &entry->mux;
- entry->mux = *src;
-
-#ifdef CONFIG_OMAP_MUX
- if (omap_mux_copy_names(src, m)) {
- kfree(entry);
- return NULL;
- }
-#endif
-
- mutex_lock(&muxmode_mutex);
- list_add_tail(&entry->node, &partition->muxmodes);
- mutex_unlock(&muxmode_mutex);
-
- return m;
-}
-
-/*
- * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
- * the GPIO to mux offset mapping that is needed for dynamic muxing
- * of GPIO pins for off-idle.
- */
-static void __init omap_mux_init_list(struct omap_mux_partition *partition,
- struct omap_mux *superset)
-{
- while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
- struct omap_mux *entry;
-
-#ifdef CONFIG_OMAP_MUX
- if (!superset->muxnames[0]) {
- superset++;
- continue;
- }
-#else
- /* Skip pins that are not muxed as GPIO by bootloader */
- if (!OMAP_MODE_GPIO(partition, omap_mux_read(partition,
- superset->reg_offset))) {
- superset++;
- continue;
- }
-#endif
-
- entry = omap_mux_list_add(partition, superset);
- if (!entry) {
- pr_err("%s: Could not add entry\n", __func__);
- return;
- }
- superset++;
- }
-}
-
-#ifdef CONFIG_OMAP_MUX
-
-static void omap_mux_init_package(struct omap_mux *superset,
- struct omap_mux *package_subset,
- struct omap_ball *package_balls)
-{
- if (package_subset)
- omap_mux_package_fixup(package_subset, superset);
- if (package_balls)
- omap_mux_package_init_balls(package_balls, superset);
-}
-
-static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
- struct omap_board_mux *board_mux)
-{
- omap_mux_set_cmdline_signals();
- omap_mux_write_array(partition, board_mux);
-}
-
-#else
-
-static void omap_mux_init_package(struct omap_mux *superset,
- struct omap_mux *package_subset,
- struct omap_ball *package_balls)
-{
-}
-
-static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
- struct omap_board_mux *board_mux)
-{
-}
-
-#endif
-
-static u32 mux_partitions_cnt;
-
-int __init omap_mux_init(const char *name, u32 flags,
- u32 mux_pbase, u32 mux_size,
- struct omap_mux *superset,
- struct omap_mux *package_subset,
- struct omap_board_mux *board_mux,
- struct omap_ball *package_balls)
-{
- struct omap_mux_partition *partition;
-
- partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
- if (!partition)
- return -ENOMEM;
-
- partition->name = name;
- partition->flags = flags;
- partition->gpio = flags & OMAP_MUX_MODE7;
- partition->size = mux_size;
- partition->phys = mux_pbase;
- partition->base = ioremap(mux_pbase, mux_size);
- if (!partition->base) {
- pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
- __func__, partition->phys);
- kfree(partition);
- return -ENODEV;
- }
-
- INIT_LIST_HEAD(&partition->muxmodes);
-
- list_add_tail(&partition->node, &mux_partitions);
- mux_partitions_cnt++;
- pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
- mux_partitions_cnt, partition->name, partition->flags);
-
- omap_mux_init_package(superset, package_subset, package_balls);
- omap_mux_init_list(partition, superset);
- omap_mux_init_signals(partition, board_mux);
-
- return 0;
-}
-
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
deleted file mode 100644
index d121fb6df4e6..000000000000
--- a/arch/arm/mach-omap2/mux.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2009 Nokia
- * Copyright (C) 2009-2010 Texas Instruments
- *
- * 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 "mux34xx.h"
-
-#define OMAP_MUX_TERMINATOR 0xffff
-
-/* 34xx mux mode options for each pin. See TRM for options */
-#define OMAP_MUX_MODE0 0
-#define OMAP_MUX_MODE1 1
-#define OMAP_MUX_MODE2 2
-#define OMAP_MUX_MODE3 3
-#define OMAP_MUX_MODE4 4
-#define OMAP_MUX_MODE5 5
-#define OMAP_MUX_MODE6 6
-#define OMAP_MUX_MODE7 7
-
-/* 24xx/34xx mux bit defines */
-#define OMAP_PULL_ENA (1 << 3)
-#define OMAP_PULL_UP (1 << 4)
-#define OMAP_ALTELECTRICALSEL (1 << 5)
-
-/* omap3/4/5 specific mux bit defines */
-#define OMAP_INPUT_EN (1 << 8)
-#define OMAP_OFF_EN (1 << 9)
-#define OMAP_OFFOUT_EN (1 << 10)
-#define OMAP_OFFOUT_VAL (1 << 11)
-#define OMAP_OFF_PULL_EN (1 << 12)
-#define OMAP_OFF_PULL_UP (1 << 13)
-#define OMAP_WAKEUP_EN (1 << 14)
-#define OMAP_WAKEUP_EVENT (1 << 15)
-
-/* Active pin states */
-#define OMAP_PIN_OUTPUT 0
-#define OMAP_PIN_INPUT OMAP_INPUT_EN
-#define OMAP_PIN_INPUT_PULLUP (OMAP_PULL_ENA | OMAP_INPUT_EN \
- | OMAP_PULL_UP)
-#define OMAP_PIN_INPUT_PULLDOWN (OMAP_PULL_ENA | OMAP_INPUT_EN)
-
-/* Off mode states */
-#define OMAP_PIN_OFF_NONE 0
-#define OMAP_PIN_OFF_OUTPUT_HIGH (OMAP_OFF_EN | OMAP_OFFOUT_EN \
- | OMAP_OFFOUT_VAL)
-#define OMAP_PIN_OFF_OUTPUT_LOW (OMAP_OFF_EN | OMAP_OFFOUT_EN)
-#define OMAP_PIN_OFF_INPUT_PULLUP (OMAP_OFF_EN | OMAP_OFF_PULL_EN \
- | OMAP_OFF_PULL_UP)
-#define OMAP_PIN_OFF_INPUT_PULLDOWN (OMAP_OFF_EN | OMAP_OFF_PULL_EN)
-#define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN
-
-#define OMAP_MODE_GPIO(partition, x) (((x) & OMAP_MUX_MODE7) == \
- partition->gpio)
-#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0)
-
-/* Flags for omapX_mux_init */
-#define OMAP_PACKAGE_MASK 0xffff
-#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */
-#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */
-#define OMAP_PACKAGE_CBB 4 /* 515-pin 0.40 0.50 */
-#define OMAP_PACKAGE_CBC 3 /* 515-pin 0.50 0.65 */
-
-#define OMAP_MUX_NR_MODES 8 /* Available modes */
-#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */
-
-/*
- * omap_mux_init flags definition:
- *
- * OMAP_GPIO_MUX_MODE, bits 0-2: gpio muxing mode, same like pad control
- * register which includes values from 0-7.
- * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
- * The default value is 16 bits.
- */
-#define OMAP_MUX_GPIO_IN_MODE0 OMAP_MUX_MODE0
-#define OMAP_MUX_GPIO_IN_MODE1 OMAP_MUX_MODE1
-#define OMAP_MUX_GPIO_IN_MODE2 OMAP_MUX_MODE2
-#define OMAP_MUX_GPIO_IN_MODE3 OMAP_MUX_MODE3
-#define OMAP_MUX_GPIO_IN_MODE4 OMAP_MUX_MODE4
-#define OMAP_MUX_GPIO_IN_MODE5 OMAP_MUX_MODE5
-#define OMAP_MUX_GPIO_IN_MODE6 OMAP_MUX_MODE6
-#define OMAP_MUX_GPIO_IN_MODE7 OMAP_MUX_MODE7
-#define OMAP_MUX_REG_8BIT (1 << 3)
-
-/**
- * struct omap_board_data - board specific device data
- * @id: instance id
- * @flags: additional flags for platform init code
- * @pads: array of device specific pads
- * @pads_cnt: ARRAY_SIZE() of pads
- */
-struct omap_board_data {
- int id;
- u32 flags;
- struct omap_device_pad *pads;
- int pads_cnt;
-};
-
-/**
- * struct mux_partition - contain partition related information
- * @name: name of the current partition
- * @flags: flags specific to this partition
- * @gpio: gpio mux mode
- * @phys: physical address
- * @size: partition size
- * @base: virtual address after ioremap
- * @muxmodes: list of nodes that belong to a partition
- * @node: list node for the partitions linked list
- */
-struct omap_mux_partition {
- const char *name;
- u32 flags;
- u32 gpio;
- u32 phys;
- u32 size;
- void __iomem *base;
- struct list_head muxmodes;
- struct list_head node;
-};
-
-/**
- * struct omap_mux - data for omap mux register offset and it's value
- * @reg_offset: mux register offset from the mux base
- * @gpio: GPIO number
- * @muxnames: available signal modes for a ball
- * @balls: available balls on the package
- */
-struct omap_mux {
- u16 reg_offset;
- u16 gpio;
-#ifdef CONFIG_OMAP_MUX
- char *muxnames[OMAP_MUX_NR_MODES];
-#ifdef CONFIG_DEBUG_FS
- char *balls[OMAP_MUX_NR_SIDES];
-#endif
-#endif
-};
-
-/**
- * struct omap_ball - data for balls on omap package
- * @reg_offset: mux register offset from the mux base
- * @balls: available balls on the package
- */
-struct omap_ball {
- u16 reg_offset;
- char *balls[OMAP_MUX_NR_SIDES];
-};
-
-/**
- * struct omap_board_mux - data for initializing mux registers
- * @reg_offset: mux register offset from the mux base
- * @mux_value: desired mux value to set
- */
-struct omap_board_mux {
- u16 reg_offset;
- u16 value;
-};
-
-#define OMAP_DEVICE_PAD_REMUX BIT(1) /* Dynamically remux a pad,
- needs enable, idle and off
- values */
-#define OMAP_DEVICE_PAD_WAKEUP BIT(0) /* Pad is wake-up capable */
-
-/**
- * struct omap_device_pad - device specific pad configuration
- * @name: signal name
- * @flags: pad specific runtime flags
- * @enable: runtime value for a pad
- * @idle: idle value for a pad
- * @off: off value for a pad, defaults to safe mode
- * @partition: mux partition
- * @mux: mux register
- */
-struct omap_device_pad {
- char *name;
- u8 flags;
- u16 enable;
- u16 idle;
- u16 off;
- struct omap_mux_partition *partition;
- struct omap_mux *mux;
-};
-
-struct omap_hwmod_mux_info;
-
-#define OMAP_MUX_STATIC(signal, mode) \
-{ \
- .name = (signal), \
- .enable = (mode), \
-}
-
-#if defined(CONFIG_OMAP_MUX)
-
-/**
- * omap_mux_init_gpio - initialize a signal based on the GPIO number
- * @gpio: GPIO number
- * @val: Options for the mux register value
- */
-int omap_mux_init_gpio(int gpio, int val);
-
-/**
- * omap_mux_init_signal - initialize a signal based on the signal name
- * @muxname: Mux name in mode0_name.signal_name format
- * @val: Options for the mux register value
- */
-int omap_mux_init_signal(const char *muxname, int val);
-
-/**
- * omap_hwmod_mux_init - initialize hwmod specific mux data
- * @bpads: Board specific device signal names
- * @nr_pads: Number of signal names for the device
- */
-extern struct omap_hwmod_mux_info *
-omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
-
-/**
- * omap_hwmod_mux - omap hwmod specific pin muxing
- * @hmux: Pads for a hwmod
- * @state: Desired _HWMOD_STATE
- *
- * Called only from omap_hwmod.c, do not use.
- */
-void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
-
-int omap_mux_get_by_name(const char *muxname,
- struct omap_mux_partition **found_partition,
- struct omap_mux **found_mux);
-#else
-
-static inline int omap_mux_get_by_name(const char *muxname,
- struct omap_mux_partition **found_partition,
- struct omap_mux **found_mux)
-{
- return 0;
-}
-
-static inline int omap_mux_init_gpio(int gpio, int val)
-{
- return 0;
-}
-static inline int omap_mux_init_signal(char *muxname, int val)
-{
- return 0;
-}
-
-static inline struct omap_hwmod_mux_info *
-omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
-{
- return NULL;
-}
-
-static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
-{
-}
-
-static struct omap_board_mux *board_mux __maybe_unused;
-
-#endif
-
-/**
- * omap_mux_get_gpio() - get mux register value based on GPIO number
- * @gpio: GPIO number
- *
- */
-u16 omap_mux_get_gpio(int gpio);
-
-/**
- * omap_mux_set_gpio() - set mux register value based on GPIO number
- * @val: New mux register value
- * @gpio: GPIO number
- *
- */
-void omap_mux_set_gpio(u16 val, int gpio);
-
-/**
- * omap_mux_get() - get a mux partition by name
- * @name: Name of the mux partition
- *
- */
-struct omap_mux_partition *omap_mux_get(const char *name);
-
-/**
- * omap_mux_read() - read mux register
- * @partition: Mux partition
- * @mux_offset: Offset of the mux register
- *
- */
-u16 omap_mux_read(struct omap_mux_partition *p, u16 mux_offset);
-
-/**
- * omap_mux_write() - write mux register
- * @partition: Mux partition
- * @val: New mux register value
- * @mux_offset: Offset of the mux register
- *
- * This should be only needed for dynamic remuxing of non-gpio signals.
- */
-void omap_mux_write(struct omap_mux_partition *p, u16 val, u16 mux_offset);
-
-/**
- * omap_mux_write_array() - write an array of mux registers
- * @partition: Mux partition
- * @board_mux: Array of mux registers terminated by MAP_MUX_TERMINATOR
- *
- * This should be only needed for dynamic remuxing of non-gpio signals.
- */
-void omap_mux_write_array(struct omap_mux_partition *p,
- struct omap_board_mux *board_mux);
-
-/**
- * omap2420_mux_init() - initialize mux system with board specific set
- * @board_mux: Board specific mux table
- * @flags: OMAP package type used for the board
- */
-int omap2420_mux_init(struct omap_board_mux *board_mux, int flags);
-
-/**
- * omap2430_mux_init() - initialize mux system with board specific set
- * @board_mux: Board specific mux table
- * @flags: OMAP package type used for the board
- */
-int omap2430_mux_init(struct omap_board_mux *board_mux, int flags);
-
-/**
- * omap3_mux_init() - initialize mux system with board specific set
- * @board_mux: Board specific mux table
- * @flags: OMAP package type used for the board
- */
-int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
-
-/**
- * omap4_mux_init() - initialize mux system with board specific set
- * @board_subset: Board specific mux table
- * @board_wkup_subset: Board specific mux table for wakeup instance
- * @flags: OMAP package type used for the board
- */
-int omap4_mux_init(struct omap_board_mux *board_subset,
- struct omap_board_mux *board_wkup_subset, int flags);
-
-/**
- * omap_mux_init - private mux init function, do not call
- */
-int omap_mux_init(const char *name, u32 flags,
- u32 mux_pbase, u32 mux_size,
- struct omap_mux *superset,
- struct omap_mux *package_subset,
- struct omap_board_mux *board_mux,
- struct omap_ball *package_balls);
-
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
deleted file mode 100644
index 393e687f99e2..000000000000
--- a/arch/arm/mach-omap2/mux34xx.c
+++ /dev/null
@@ -1,2061 +0,0 @@
-/*
- * Copyright (C) 2009 Nokia
- * Copyright (C) 2009 Texas Instruments
- *
- * 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/module.h>
-#include <linux/init.h>
-
-#include "mux.h"
-
-#ifdef CONFIG_OMAP_MUX
-
-#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
-{ \
- .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \
- .gpio = (g), \
- .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
-}
-
-#else
-
-#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
-{ \
- .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \
- .gpio = (g), \
-}
-
-#endif
-
-#define _OMAP3_BALLENTRY(M0, bb, bt) \
-{ \
- .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \
- .balls = { bb, bt }, \
-}
-
-/*
- * Superset of all mux modes for omap3
- */
-static struct omap_mux __initdata omap3_muxmodes[] = {
- _OMAP3_MUXENTRY(CAM_D0, 99,
- "cam_d0", NULL, NULL, NULL,
- "gpio_99", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D1, 100,
- "cam_d1", NULL, NULL, NULL,
- "gpio_100", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D10, 109,
- "cam_d10", NULL, NULL, NULL,
- "gpio_109", "hw_dbg8", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D11, 110,
- "cam_d11", NULL, NULL, NULL,
- "gpio_110", "hw_dbg9", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D2, 101,
- "cam_d2", NULL, NULL, NULL,
- "gpio_101", "hw_dbg4", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D3, 102,
- "cam_d3", NULL, NULL, NULL,
- "gpio_102", "hw_dbg5", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D4, 103,
- "cam_d4", NULL, NULL, NULL,
- "gpio_103", "hw_dbg6", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D5, 104,
- "cam_d5", NULL, NULL, NULL,
- "gpio_104", "hw_dbg7", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D6, 105,
- "cam_d6", NULL, NULL, NULL,
- "gpio_105", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D7, 106,
- "cam_d7", NULL, NULL, NULL,
- "gpio_106", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D8, 107,
- "cam_d8", NULL, NULL, NULL,
- "gpio_107", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D9, 108,
- "cam_d9", NULL, NULL, NULL,
- "gpio_108", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_FLD, 98,
- "cam_fld", NULL, "cam_global_reset", NULL,
- "gpio_98", "hw_dbg3", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_HS, 94,
- "cam_hs", NULL, NULL, NULL,
- "gpio_94", "hw_dbg0", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_PCLK, 97,
- "cam_pclk", NULL, NULL, NULL,
- "gpio_97", "hw_dbg2", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_STROBE, 126,
- "cam_strobe", NULL, NULL, NULL,
- "gpio_126", "hw_dbg11", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_VS, 95,
- "cam_vs", NULL, NULL, NULL,
- "gpio_95", "hw_dbg1", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_WEN, 167,
- "cam_wen", NULL, "cam_shutter", NULL,
- "gpio_167", "hw_dbg10", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_XCLKA, 96,
- "cam_xclka", NULL, NULL, NULL,
- "gpio_96", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_XCLKB, 111,
- "cam_xclkb", NULL, NULL, NULL,
- "gpio_111", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CSI2_DX0, 112,
- "csi2_dx0", NULL, NULL, NULL,
- "gpio_112", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CSI2_DX1, 114,
- "csi2_dx1", NULL, NULL, NULL,
- "gpio_114", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CSI2_DY0, 113,
- "csi2_dy0", NULL, NULL, NULL,
- "gpio_113", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CSI2_DY1, 115,
- "csi2_dy1", NULL, NULL, NULL,
- "gpio_115", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_ACBIAS, 69,
- "dss_acbias", NULL, NULL, NULL,
- "gpio_69", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA0, 70,
- "dss_data0", NULL, "uart1_cts", NULL,
- "gpio_70", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA1, 71,
- "dss_data1", NULL, "uart1_rts", NULL,
- "gpio_71", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA10, 80,
- "dss_data10", NULL, NULL, NULL,
- "gpio_80", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA11, 81,
- "dss_data11", NULL, NULL, NULL,
- "gpio_81", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA12, 82,
- "dss_data12", NULL, NULL, NULL,
- "gpio_82", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA13, 83,
- "dss_data13", NULL, NULL, NULL,
- "gpio_83", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA14, 84,
- "dss_data14", NULL, NULL, NULL,
- "gpio_84", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA15, 85,
- "dss_data15", NULL, NULL, NULL,
- "gpio_85", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA16, 86,
- "dss_data16", NULL, NULL, NULL,
- "gpio_86", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA17, 87,
- "dss_data17", NULL, NULL, NULL,
- "gpio_87", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA18, 88,
- "dss_data18", NULL, "mcspi3_clk", "dss_data0",
- "gpio_88", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA19, 89,
- "dss_data19", NULL, "mcspi3_simo", "dss_data1",
- "gpio_89", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA20, 90,
- "dss_data20", NULL, "mcspi3_somi", "dss_data2",
- "gpio_90", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA21, 91,
- "dss_data21", NULL, "mcspi3_cs0", "dss_data3",
- "gpio_91", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA22, 92,
- "dss_data22", NULL, "mcspi3_cs1", "dss_data4",
- "gpio_92", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA23, 93,
- "dss_data23", NULL, NULL, "dss_data5",
- "gpio_93", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA2, 72,
- "dss_data2", NULL, NULL, NULL,
- "gpio_72", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA3, 73,
- "dss_data3", NULL, NULL, NULL,
- "gpio_73", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA4, 74,
- "dss_data4", NULL, "uart3_rx_irrx", NULL,
- "gpio_74", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA5, 75,
- "dss_data5", NULL, "uart3_tx_irtx", NULL,
- "gpio_75", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA6, 76,
- "dss_data6", NULL, "uart1_tx", NULL,
- "gpio_76", "hw_dbg14", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA7, 77,
- "dss_data7", NULL, "uart1_rx", NULL,
- "gpio_77", "hw_dbg15", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA8, 78,
- "dss_data8", NULL, NULL, NULL,
- "gpio_78", "hw_dbg16", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA9, 79,
- "dss_data9", NULL, NULL, NULL,
- "gpio_79", "hw_dbg17", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_HSYNC, 67,
- "dss_hsync", NULL, NULL, NULL,
- "gpio_67", "hw_dbg13", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_PCLK, 66,
- "dss_pclk", NULL, NULL, NULL,
- "gpio_66", "hw_dbg12", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_VSYNC, 68,
- "dss_vsync", NULL, NULL, NULL,
- "gpio_68", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(ETK_CLK, 12,
- "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
- "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", "hw_dbg0"),
- _OMAP3_MUXENTRY(ETK_CTL, 13,
- "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
- "gpio_13", NULL, "hsusb1_tll_clk", "hw_dbg1"),
- _OMAP3_MUXENTRY(ETK_D0, 14,
- "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
- "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", "hw_dbg2"),
- _OMAP3_MUXENTRY(ETK_D1, 15,
- "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
- "gpio_15", "mm1_txse0", "hsusb1_tll_data1", "hw_dbg3"),
- _OMAP3_MUXENTRY(ETK_D10, 24,
- "etk_d10", NULL, "uart1_rx", "hsusb2_clk",
- "gpio_24", NULL, "hsusb2_tll_clk", "hw_dbg12"),
- _OMAP3_MUXENTRY(ETK_D11, 25,
- "etk_d11", NULL, NULL, "hsusb2_stp",
- "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", "hw_dbg13"),
- _OMAP3_MUXENTRY(ETK_D12, 26,
- "etk_d12", NULL, NULL, "hsusb2_dir",
- "gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"),
- _OMAP3_MUXENTRY(ETK_D13, 27,
- "etk_d13", NULL, NULL, "hsusb2_nxt",
- "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", "hw_dbg15"),
- _OMAP3_MUXENTRY(ETK_D14, 28,
- "etk_d14", NULL, NULL, "hsusb2_data0",
- "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", "hw_dbg16"),
- _OMAP3_MUXENTRY(ETK_D15, 29,
- "etk_d15", NULL, NULL, "hsusb2_data1",
- "gpio_29", "mm2_txse0", "hsusb2_tll_data1", "hw_dbg17"),
- _OMAP3_MUXENTRY(ETK_D2, 16,
- "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
- "gpio_16", "mm1_txdat", "hsusb1_tll_data2", "hw_dbg4"),
- _OMAP3_MUXENTRY(ETK_D3, 17,
- "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
- "gpio_17", NULL, "hsusb1_tll_data7", "hw_dbg5"),
- _OMAP3_MUXENTRY(ETK_D4, 18,
- "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
- "gpio_18", NULL, "hsusb1_tll_data4", "hw_dbg6"),
- _OMAP3_MUXENTRY(ETK_D5, 19,
- "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
- "gpio_19", NULL, "hsusb1_tll_data5", "hw_dbg7"),
- _OMAP3_MUXENTRY(ETK_D6, 20,
- "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
- "gpio_20", NULL, "hsusb1_tll_data6", "hw_dbg8"),
- _OMAP3_MUXENTRY(ETK_D7, 21,
- "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
- "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", "hw_dbg9"),
- _OMAP3_MUXENTRY(ETK_D8, 22,
- "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
- "gpio_22", NULL, "hsusb1_tll_dir", "hw_dbg10"),
- _OMAP3_MUXENTRY(ETK_D9, 23,
- "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
- "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", "hw_dbg11"),
- _OMAP3_MUXENTRY(GPMC_A1, 34,
- "gpmc_a1", NULL, NULL, NULL,
- "gpio_34", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A10, 43,
- "gpmc_a10", "sys_ndmareq3", NULL, NULL,
- "gpio_43", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A2, 35,
- "gpmc_a2", NULL, NULL, NULL,
- "gpio_35", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A3, 36,
- "gpmc_a3", NULL, NULL, NULL,
- "gpio_36", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A4, 37,
- "gpmc_a4", NULL, NULL, NULL,
- "gpio_37", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A5, 38,
- "gpmc_a5", NULL, NULL, NULL,
- "gpio_38", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A6, 39,
- "gpmc_a6", NULL, NULL, NULL,
- "gpio_39", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A7, 40,
- "gpmc_a7", NULL, NULL, NULL,
- "gpio_40", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A8, 41,
- "gpmc_a8", NULL, NULL, NULL,
- "gpio_41", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_A9, 42,
- "gpmc_a9", "sys_ndmareq2", NULL, NULL,
- "gpio_42", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_CLK, 59,
- "gpmc_clk", NULL, NULL, NULL,
- "gpio_59", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D10, 46,
- "gpmc_d10", NULL, NULL, NULL,
- "gpio_46", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D11, 47,
- "gpmc_d11", NULL, NULL, NULL,
- "gpio_47", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D12, 48,
- "gpmc_d12", NULL, NULL, NULL,
- "gpio_48", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D13, 49,
- "gpmc_d13", NULL, NULL, NULL,
- "gpio_49", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D14, 50,
- "gpmc_d14", NULL, NULL, NULL,
- "gpio_50", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D15, 51,
- "gpmc_d15", NULL, NULL, NULL,
- "gpio_51", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D8, 44,
- "gpmc_d8", NULL, NULL, NULL,
- "gpio_44", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_D9, 45,
- "gpmc_d9", NULL, NULL, NULL,
- "gpio_45", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NBE0_CLE, 60,
- "gpmc_nbe0_cle", NULL, NULL, NULL,
- "gpio_60", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NBE1, 61,
- "gpmc_nbe1", NULL, NULL, NULL,
- "gpio_61", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS1, 52,
- "gpmc_ncs1", NULL, NULL, NULL,
- "gpio_52", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS2, 53,
- "gpmc_ncs2", NULL, NULL, NULL,
- "gpio_53", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS3, 54,
- "gpmc_ncs3", "sys_ndmareq0", NULL, NULL,
- "gpio_54", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS4, 55,
- "gpmc_ncs4", "sys_ndmareq1", "mcbsp4_clkx", "gpt9_pwm_evt",
- "gpio_55", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS5, 56,
- "gpmc_ncs5", "sys_ndmareq2", "mcbsp4_dr", "gpt10_pwm_evt",
- "gpio_56", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS6, 57,
- "gpmc_ncs6", "sys_ndmareq3", "mcbsp4_dx", "gpt11_pwm_evt",
- "gpio_57", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NCS7, 58,
- "gpmc_ncs7", "gpmc_io_dir", "mcbsp4_fsx", "gpt8_pwm_evt",
- "gpio_58", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_NWP, 62,
- "gpmc_nwp", NULL, NULL, NULL,
- "gpio_62", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_WAIT1, 63,
- "gpmc_wait1", NULL, NULL, NULL,
- "gpio_63", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_WAIT2, 64,
- "gpmc_wait2", NULL, NULL, NULL,
- "gpio_64", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_WAIT3, 65,
- "gpmc_wait3", "sys_ndmareq1", NULL, NULL,
- "gpio_65", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HDQ_SIO, 170,
- "hdq_sio", "sys_altclk", "i2c2_sccbe", "i2c3_sccbe",
- "gpio_170", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_CLK, 120,
- "hsusb0_clk", NULL, NULL, NULL,
- "gpio_120", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA0, 125,
- "hsusb0_data0", NULL, "uart3_tx_irtx", NULL,
- "gpio_125", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA1, 130,
- "hsusb0_data1", NULL, "uart3_rx_irrx", NULL,
- "gpio_130", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA2, 131,
- "hsusb0_data2", NULL, "uart3_rts_sd", NULL,
- "gpio_131", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA3, 169,
- "hsusb0_data3", NULL, "uart3_cts_rctx", NULL,
- "gpio_169", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA4, 188,
- "hsusb0_data4", NULL, NULL, NULL,
- "gpio_188", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA5, 189,
- "hsusb0_data5", NULL, NULL, NULL,
- "gpio_189", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA6, 190,
- "hsusb0_data6", NULL, NULL, NULL,
- "gpio_190", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA7, 191,
- "hsusb0_data7", NULL, NULL, NULL,
- "gpio_191", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DIR, 122,
- "hsusb0_dir", NULL, NULL, NULL,
- "gpio_122", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_NXT, 124,
- "hsusb0_nxt", NULL, NULL, NULL,
- "gpio_124", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_STP, 121,
- "hsusb0_stp", NULL, NULL, NULL,
- "gpio_121", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(I2C2_SCL, 168,
- "i2c2_scl", NULL, NULL, NULL,
- "gpio_168", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(I2C2_SDA, 183,
- "i2c2_sda", NULL, NULL, NULL,
- "gpio_183", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(I2C3_SCL, 184,
- "i2c3_scl", NULL, NULL, NULL,
- "gpio_184", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(I2C3_SDA, 185,
- "i2c3_sda", NULL, NULL, NULL,
- "gpio_185", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(I2C4_SCL, 0,
- "i2c4_scl", "sys_nvmode1", NULL, NULL,
- NULL, NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(I2C4_SDA, 0,
- "i2c4_sda", "sys_nvmode2", NULL, NULL,
- NULL, NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(JTAG_EMU0, 11,
- "jtag_emu0", NULL, NULL, NULL,
- "gpio_11", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(JTAG_EMU1, 31,
- "jtag_emu1", NULL, NULL, NULL,
- "gpio_31", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_CLKR, 156,
- "mcbsp1_clkr", "mcspi4_clk", NULL, NULL,
- "gpio_156", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_CLKX, 162,
- "mcbsp1_clkx", NULL, "mcbsp3_clkx", NULL,
- "gpio_162", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_DR, 159,
- "mcbsp1_dr", "mcspi4_somi", "mcbsp3_dr", NULL,
- "gpio_159", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_DX, 158,
- "mcbsp1_dx", "mcspi4_simo", "mcbsp3_dx", NULL,
- "gpio_158", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_FSR, 157,
- "mcbsp1_fsr", NULL, "cam_global_reset", NULL,
- "gpio_157", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_FSX, 161,
- "mcbsp1_fsx", "mcspi4_cs0", "mcbsp3_fsx", NULL,
- "gpio_161", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP2_CLKX, 117,
- "mcbsp2_clkx", NULL, NULL, NULL,
- "gpio_117", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP2_DR, 118,
- "mcbsp2_dr", NULL, NULL, NULL,
- "gpio_118", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP2_DX, 119,
- "mcbsp2_dx", NULL, NULL, NULL,
- "gpio_119", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP2_FSX, 116,
- "mcbsp2_fsx", NULL, NULL, NULL,
- "gpio_116", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_CLKX, 142,
- "mcbsp3_clkx", "uart2_tx", NULL, NULL,
- "gpio_142", "hsusb3_tll_data6", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_DR, 141,
- "mcbsp3_dr", "uart2_rts", NULL, NULL,
- "gpio_141", "hsusb3_tll_data5", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_DX, 140,
- "mcbsp3_dx", "uart2_cts", NULL, NULL,
- "gpio_140", "hsusb3_tll_data4", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_FSX, 143,
- "mcbsp3_fsx", "uart2_rx", NULL, NULL,
- "gpio_143", "hsusb3_tll_data7", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_CLKX, 152,
- "mcbsp4_clkx", NULL, NULL, NULL,
- "gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_DR, 153,
- "mcbsp4_dr", NULL, NULL, NULL,
- "gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_DX, 154,
- "mcbsp4_dx", NULL, NULL, NULL,
- "gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_FSX, 155,
- "mcbsp4_fsx", NULL, NULL, NULL,
- "gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP_CLKS, 160,
- "mcbsp_clks", NULL, "cam_shutter", NULL,
- "gpio_160", "uart1_cts", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_CLK, 171,
- "mcspi1_clk", "sdmmc2_dat4", NULL, NULL,
- "gpio_171", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_CS0, 174,
- "mcspi1_cs0", "sdmmc2_dat7", NULL, NULL,
- "gpio_174", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_CS1, 175,
- "mcspi1_cs1", NULL, NULL, "sdmmc3_cmd",
- "gpio_175", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_CS2, 176,
- "mcspi1_cs2", NULL, NULL, "sdmmc3_clk",
- "gpio_176", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_CS3, 177,
- "mcspi1_cs3", NULL, "hsusb2_tll_data2", "hsusb2_data2",
- "gpio_177", "mm2_txdat", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_SIMO, 172,
- "mcspi1_simo", "sdmmc2_dat5", NULL, NULL,
- "gpio_172", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_SOMI, 173,
- "mcspi1_somi", "sdmmc2_dat6", NULL, NULL,
- "gpio_173", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI2_CLK, 178,
- "mcspi2_clk", NULL, "hsusb2_tll_data7", "hsusb2_data7",
- "gpio_178", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI2_CS0, 181,
- "mcspi2_cs0", "gpt11_pwm_evt",
- "hsusb2_tll_data6", "hsusb2_data6",
- "gpio_181", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI2_CS1, 182,
- "mcspi2_cs1", "gpt8_pwm_evt",
- "hsusb2_tll_data3", "hsusb2_data3",
- "gpio_182", "mm2_txen_n", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI2_SIMO, 179,
- "mcspi2_simo", "gpt9_pwm_evt",
- "hsusb2_tll_data4", "hsusb2_data4",
- "gpio_179", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI2_SOMI, 180,
- "mcspi2_somi", "gpt10_pwm_evt",
- "hsusb2_tll_data5", "hsusb2_data5",
- "gpio_180", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_CLK, 120,
- "sdmmc1_clk", NULL, NULL, NULL,
- "gpio_120", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_CMD, 121,
- "sdmmc1_cmd", NULL, NULL, NULL,
- "gpio_121", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT0, 122,
- "sdmmc1_dat0", NULL, NULL, NULL,
- "gpio_122", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT1, 123,
- "sdmmc1_dat1", NULL, NULL, NULL,
- "gpio_123", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT2, 124,
- "sdmmc1_dat2", NULL, NULL, NULL,
- "gpio_124", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT3, 125,
- "sdmmc1_dat3", NULL, NULL, NULL,
- "gpio_125", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT4, 126,
- "sdmmc1_dat4", NULL, "sim_io", NULL,
- "gpio_126", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT5, 127,
- "sdmmc1_dat5", NULL, "sim_clk", NULL,
- "gpio_127", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT6, 128,
- "sdmmc1_dat6", NULL, "sim_pwrctrl", NULL,
- "gpio_128", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT7, 129,
- "sdmmc1_dat7", NULL, "sim_rst", NULL,
- "gpio_129", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_CLK, 130,
- "sdmmc2_clk", "mcspi3_clk", NULL, NULL,
- "gpio_130", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_CMD, 131,
- "sdmmc2_cmd", "mcspi3_simo", NULL, NULL,
- "gpio_131", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT0, 132,
- "sdmmc2_dat0", "mcspi3_somi", NULL, NULL,
- "gpio_132", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT1, 133,
- "sdmmc2_dat1", NULL, NULL, NULL,
- "gpio_133", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT2, 134,
- "sdmmc2_dat2", "mcspi3_cs1", NULL, NULL,
- "gpio_134", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT3, 135,
- "sdmmc2_dat3", "mcspi3_cs0", NULL, NULL,
- "gpio_135", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT4, 136,
- "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, "sdmmc3_dat0",
- "gpio_136", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT5, 137,
- "sdmmc2_dat5", "sdmmc2_dir_dat1",
- "cam_global_reset", "sdmmc3_dat1",
- "gpio_137", "hsusb3_tll_stp", "mm3_rxdp", "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT6, 138,
- "sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2",
- "gpio_138", "hsusb3_tll_dir", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT7, 139,
- "sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3",
- "gpio_139", "hsusb3_tll_nxt", "mm3_rxdm", "safe_mode"),
- _OMAP3_MUXENTRY(SDRC_CKE0, 0,
- "sdrc_cke0", NULL, NULL, NULL,
- NULL, NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDRC_CKE1, 0,
- "sdrc_cke1", NULL, NULL, NULL,
- NULL, NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT0, 2,
- "sys_boot0", NULL, NULL, NULL,
- "gpio_2", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT1, 3,
- "sys_boot1", NULL, NULL, NULL,
- "gpio_3", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT2, 4,
- "sys_boot2", NULL, NULL, NULL,
- "gpio_4", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT3, 5,
- "sys_boot3", NULL, NULL, NULL,
- "gpio_5", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT4, 6,
- "sys_boot4", "sdmmc2_dir_dat2", NULL, NULL,
- "gpio_6", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT5, 7,
- "sys_boot5", "sdmmc2_dir_dat3", NULL, NULL,
- "gpio_7", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT6, 8,
- "sys_boot6", NULL, NULL, NULL,
- "gpio_8", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_CLKOUT1, 10,
- "sys_clkout1", NULL, NULL, NULL,
- "gpio_10", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_CLKOUT2, 186,
- "sys_clkout2", NULL, NULL, NULL,
- "gpio_186", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_CLKREQ, 1,
- "sys_clkreq", NULL, NULL, NULL,
- "gpio_1", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_NIRQ, 0,
- "sys_nirq", NULL, NULL, NULL,
- "gpio_0", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_NRESWARM, 30,
- "sys_nreswarm", NULL, NULL, NULL,
- "gpio_30", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_OFF_MODE, 9,
- "sys_off_mode", NULL, NULL, NULL,
- "gpio_9", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_CTS, 150,
- "uart1_cts", "ssi1_rdy_tx", NULL, NULL,
- "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_RTS, 149,
- "uart1_rts", "ssi1_flag_tx", NULL, NULL,
- "gpio_149", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_RX, 151,
- "uart1_rx", "ssi1_wake_tx", "mcbsp1_clkr", "mcspi4_clk",
- "gpio_151", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_TX, 148,
- "uart1_tx", "ssi1_dat_tx", NULL, NULL,
- "gpio_148", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART2_CTS, 144,
- "uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL,
- "gpio_144", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART2_RTS, 145,
- "uart2_rts", "mcbsp3_dr", "gpt10_pwm_evt", NULL,
- "gpio_145", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART2_RX, 147,
- "uart2_rx", "mcbsp3_fsx", "gpt8_pwm_evt", NULL,
- "gpio_147", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART2_TX, 146,
- "uart2_tx", "mcbsp3_clkx", "gpt11_pwm_evt", NULL,
- "gpio_146", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART3_CTS_RCTX, 163,
- "uart3_cts_rctx", NULL, NULL, NULL,
- "gpio_163", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART3_RTS_SD, 164,
- "uart3_rts_sd", NULL, NULL, NULL,
- "gpio_164", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART3_RX_IRRX, 165,
- "uart3_rx_irrx", NULL, NULL, NULL,
- "gpio_165", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART3_TX_IRTX, 166,
- "uart3_tx_irtx", NULL, NULL, NULL,
- "gpio_166", NULL, NULL, "safe_mode"),
-
- /* Only on 3630, see omap36xx_cbp_subset for the signals */
- _OMAP3_MUXENTRY(GPMC_A11, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MREAD, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MWRITE, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_SREAD, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_SWRITE, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(GPMC_A11, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD28, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD29, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD32, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD33, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD34, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD35, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD36, 0,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-/*
- * Signals different on CBC package compared to the superset
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC)
-static struct omap_mux __initdata omap3_cbc_subset[] = {
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap3_cbc_subset NULL
-#endif
-
-/*
- * Balls for CBC package
- * 515-pin s-PBGA Package, 0.65mm Ball Pitch (Top), 0.50mm Ball Pitch (Bottom)
- *
- * FIXME: What's up with the outdated TI documentation? See:
- *
- * http://wiki.davincidsp.com/index.php/Datasheet_Errata_for_OMAP35x_CBC_Package
- * http://community.ti.com/forums/t/10982.aspx
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
- && defined(CONFIG_OMAP_PACKAGE_CBC)
-static struct omap_ball __initdata omap3_cbc_ball[] = {
- _OMAP3_BALLENTRY(CAM_D0, "ae16", NULL),
- _OMAP3_BALLENTRY(CAM_D1, "ae15", NULL),
- _OMAP3_BALLENTRY(CAM_D10, "d25", NULL),
- _OMAP3_BALLENTRY(CAM_D11, "e26", NULL),
- _OMAP3_BALLENTRY(CAM_D2, "a24", NULL),
- _OMAP3_BALLENTRY(CAM_D3, "b24", NULL),
- _OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
- _OMAP3_BALLENTRY(CAM_D5, "c24", NULL),
- _OMAP3_BALLENTRY(CAM_D6, "p25", NULL),
- _OMAP3_BALLENTRY(CAM_D7, "p26", NULL),
- _OMAP3_BALLENTRY(CAM_D8, "n25", NULL),
- _OMAP3_BALLENTRY(CAM_D9, "n26", NULL),
- _OMAP3_BALLENTRY(CAM_FLD, "b23", NULL),
- _OMAP3_BALLENTRY(CAM_HS, "c23", NULL),
- _OMAP3_BALLENTRY(CAM_PCLK, "c26", NULL),
- _OMAP3_BALLENTRY(CAM_STROBE, "d26", NULL),
- _OMAP3_BALLENTRY(CAM_VS, "d23", NULL),
- _OMAP3_BALLENTRY(CAM_WEN, "a23", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKB, "e25", NULL),
- _OMAP3_BALLENTRY(CSI2_DX0, "ad17", NULL),
- _OMAP3_BALLENTRY(CSI2_DX1, "ae18", NULL),
- _OMAP3_BALLENTRY(CSI2_DY0, "ad16", NULL),
- _OMAP3_BALLENTRY(CSI2_DY1, "ae17", NULL),
- _OMAP3_BALLENTRY(DSS_ACBIAS, "f26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA0, "ae21", NULL),
- _OMAP3_BALLENTRY(DSS_DATA1, "ae22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA10, "ac26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA11, "ad26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA12, "aa25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA13, "y25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA14, "aa26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA15, "ab26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA16, "l25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA17, "l26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA18, "m24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA19, "m26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA2, "ae23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA20, "f25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA21, "n24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA22, "ac25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA23, "ab25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA3, "ae24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA4, "ad23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA5, "ad24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA6, "g26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA7, "h25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA8, "h26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA9, "j26", NULL),
- _OMAP3_BALLENTRY(DSS_HSYNC, "k24", NULL),
- _OMAP3_BALLENTRY(DSS_PCLK, "g25", NULL),
- _OMAP3_BALLENTRY(DSS_VSYNC, "m25", NULL),
- _OMAP3_BALLENTRY(ETK_CLK, "ab2", NULL),
- _OMAP3_BALLENTRY(ETK_CTL, "ab3", NULL),
- _OMAP3_BALLENTRY(ETK_D0, "ac3", NULL),
- _OMAP3_BALLENTRY(ETK_D1, "ad4", NULL),
- _OMAP3_BALLENTRY(ETK_D10, "ae4", NULL),
- _OMAP3_BALLENTRY(ETK_D11, "af6", NULL),
- _OMAP3_BALLENTRY(ETK_D12, "ae6", NULL),
- _OMAP3_BALLENTRY(ETK_D13, "af7", NULL),
- _OMAP3_BALLENTRY(ETK_D14, "af9", NULL),
- _OMAP3_BALLENTRY(ETK_D15, "ae9", NULL),
- _OMAP3_BALLENTRY(ETK_D2, "ad3", NULL),
- _OMAP3_BALLENTRY(ETK_D3, "aa3", NULL),
- _OMAP3_BALLENTRY(ETK_D4, "y3", NULL),
- _OMAP3_BALLENTRY(ETK_D5, "ab1", NULL),
- _OMAP3_BALLENTRY(ETK_D6, "ae3", NULL),
- _OMAP3_BALLENTRY(ETK_D7, "ad2", NULL),
- _OMAP3_BALLENTRY(ETK_D8, "aa4", NULL),
- _OMAP3_BALLENTRY(ETK_D9, "v2", NULL),
- _OMAP3_BALLENTRY(GPMC_A1, "j2", NULL),
- _OMAP3_BALLENTRY(GPMC_A10, "d2", NULL),
- _OMAP3_BALLENTRY(GPMC_A2, "h1", NULL),
- _OMAP3_BALLENTRY(GPMC_A3, "h2", NULL),
- _OMAP3_BALLENTRY(GPMC_A4, "g2", NULL),
- _OMAP3_BALLENTRY(GPMC_A5, "f1", NULL),
- _OMAP3_BALLENTRY(GPMC_A6, "f2", NULL),
- _OMAP3_BALLENTRY(GPMC_A7, "e1", NULL),
- _OMAP3_BALLENTRY(GPMC_A8, "e2", NULL),
- _OMAP3_BALLENTRY(GPMC_A9, "d1", NULL),
- _OMAP3_BALLENTRY(GPMC_CLK, "n1", "l1"),
- _OMAP3_BALLENTRY(GPMC_D10, "t1", "n1"),
- _OMAP3_BALLENTRY(GPMC_D11, "u2", "p2"),
- _OMAP3_BALLENTRY(GPMC_D12, "u1", "p1"),
- _OMAP3_BALLENTRY(GPMC_D13, "p1", "m1"),
- _OMAP3_BALLENTRY(GPMC_D14, "l2", "j2"),
- _OMAP3_BALLENTRY(GPMC_D15, "m2", "k2"),
- _OMAP3_BALLENTRY(GPMC_D8, "v1", "r1"),
- _OMAP3_BALLENTRY(GPMC_D9, "y1", "t1"),
- _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k2", NULL),
- _OMAP3_BALLENTRY(GPMC_NBE1, "j1", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS1, "ad1", "w1"),
- _OMAP3_BALLENTRY(GPMC_NCS2, "a3", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS3, "b6", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS4, "b4", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS5, "c4", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS6, "b5", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS7, "c5", NULL),
- _OMAP3_BALLENTRY(GPMC_NWP, "ac6", "y5"),
- _OMAP3_BALLENTRY(GPMC_WAIT1, "ac8", "y8"),
- _OMAP3_BALLENTRY(GPMC_WAIT2, "b3", NULL),
- _OMAP3_BALLENTRY(GPMC_WAIT3, "c6", NULL),
- _OMAP3_BALLENTRY(HDQ_SIO, "j23", NULL),
- _OMAP3_BALLENTRY(HSUSB0_CLK, "w19", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA0, "v20", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA1, "y20", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA2, "v18", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA3, "w20", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA4, "w17", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA5, "y18", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA6, "y19", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA7, "y17", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DIR, "v19", NULL),
- _OMAP3_BALLENTRY(HSUSB0_NXT, "w18", NULL),
- _OMAP3_BALLENTRY(HSUSB0_STP, "u20", NULL),
- _OMAP3_BALLENTRY(I2C2_SCL, "c2", NULL),
- _OMAP3_BALLENTRY(I2C2_SDA, "c1", NULL),
- _OMAP3_BALLENTRY(I2C3_SCL, "ab4", NULL),
- _OMAP3_BALLENTRY(I2C3_SDA, "ac4", NULL),
- _OMAP3_BALLENTRY(I2C4_SCL, "ad15", NULL),
- _OMAP3_BALLENTRY(I2C4_SDA, "w16", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU0, "y15", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU1, "y14", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKR, "u19", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKX, "t17", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DR, "t20", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DX, "u17", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSR, "v17", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSX, "p20", NULL),
- _OMAP3_BALLENTRY(MCBSP2_CLKX, "r18", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DR, "t18", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DX, "r19", NULL),
- _OMAP3_BALLENTRY(MCBSP2_FSX, "u18", NULL),
- _OMAP3_BALLENTRY(MCBSP3_CLKX, "u3", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DR, "n3", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DX, "p3", NULL),
- _OMAP3_BALLENTRY(MCBSP3_FSX, "w3", NULL),
- _OMAP3_BALLENTRY(MCBSP4_CLKX, "v3", NULL),
- _OMAP3_BALLENTRY(MCBSP4_DR, "u4", NULL),
- _OMAP3_BALLENTRY(MCBSP4_DX, "r3", NULL),
- _OMAP3_BALLENTRY(MCBSP4_FSX, "t3", NULL),
- _OMAP3_BALLENTRY(MCBSP_CLKS, "t19", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CLK, "p9", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS0, "r7", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS1, "r8", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS2, "r9", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS3, "t8", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SIMO, "p8", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SOMI, "p7", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CLK, "w7", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS0, "v8", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS1, "v9", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SIMO, "w8", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SOMI, "u8", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CLK, "n19", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CMD, "l18", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT0, "m19", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT1, "m18", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT2, "k18", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT3, "n20", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT4, "m20", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT5, "p17", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT6, "p18", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT7, "p19", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CLK, "w10", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CMD, "r10", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT0, "t10", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT1, "t9", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT2, "u10", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT3, "u9", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT4, "v10", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT5, "m3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT6, "l3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT7, "k3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT0, "f3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT1, "d3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT2, "c3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT3, "e3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT4, "e4", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT5, "g3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT6, "d4", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT1, "ae14", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT2, "w11", NULL),
- _OMAP3_BALLENTRY(SYS_CLKREQ, "w15", NULL),
- _OMAP3_BALLENTRY(SYS_NIRQ, "v16", NULL),
- _OMAP3_BALLENTRY(SYS_NRESWARM, "ad7", "aa5"),
- _OMAP3_BALLENTRY(SYS_OFF_MODE, "v12", NULL),
- _OMAP3_BALLENTRY(UART1_CTS, "w2", NULL),
- _OMAP3_BALLENTRY(UART1_RTS, "r2", NULL),
- _OMAP3_BALLENTRY(UART1_RX, "h3", NULL),
- _OMAP3_BALLENTRY(UART1_TX, "l4", NULL),
- _OMAP3_BALLENTRY(UART2_CTS, "y24", NULL),
- _OMAP3_BALLENTRY(UART2_RTS, "aa24", NULL),
- _OMAP3_BALLENTRY(UART2_RX, "ad21", NULL),
- _OMAP3_BALLENTRY(UART2_TX, "ad22", NULL),
- _OMAP3_BALLENTRY(UART3_CTS_RCTX, "f23", NULL),
- _OMAP3_BALLENTRY(UART3_RTS_SD, "f24", NULL),
- _OMAP3_BALLENTRY(UART3_RX_IRRX, "h24", NULL),
- _OMAP3_BALLENTRY(UART3_TX_IRTX, "g24", NULL),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap3_cbc_ball NULL
-#endif
-
-/*
- * Signals different on CUS package compared to superset
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CUS)
-static struct omap_mux __initdata omap3_cus_subset[] = {
- _OMAP3_MUXENTRY(CAM_D10, 109,
- "cam_d10", NULL, NULL, NULL,
- "gpio_109", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D11, 110,
- "cam_d11", NULL, NULL, NULL,
- "gpio_110", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D2, 101,
- "cam_d2", NULL, NULL, NULL,
- "gpio_101", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D3, 102,
- "cam_d3", NULL, NULL, NULL,
- "gpio_102", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D4, 103,
- "cam_d4", NULL, NULL, NULL,
- "gpio_103", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D5, 104,
- "cam_d5", NULL, NULL, NULL,
- "gpio_104", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_FLD, 98,
- "cam_fld", NULL, "cam_global_reset", NULL,
- "gpio_98", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_HS, 94,
- "cam_hs", NULL, NULL, NULL,
- "gpio_94", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_PCLK, 97,
- "cam_pclk", NULL, NULL, NULL,
- "gpio_97", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_STROBE, 126,
- "cam_strobe", NULL, NULL, NULL,
- "gpio_126", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_VS, 95,
- "cam_vs", NULL, NULL, NULL,
- "gpio_95", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_WEN, 167,
- "cam_wen", NULL, "cam_shutter", NULL,
- "gpio_167", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA6, 76,
- "dss_data6", NULL, "uart1_tx", NULL,
- "gpio_76", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA7, 77,
- "dss_data7", NULL, "uart1_rx", NULL,
- "gpio_77", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA8, 78,
- "dss_data8", NULL, NULL, NULL,
- "gpio_78", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA9, 79,
- "dss_data9", NULL, NULL, NULL,
- "gpio_79", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_HSYNC, 67,
- "dss_hsync", NULL, NULL, NULL,
- "gpio_67", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_PCLK, 66,
- "dss_pclk", NULL, NULL, NULL,
- "gpio_66", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(ETK_CLK, 12,
- "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
- "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL),
- _OMAP3_MUXENTRY(ETK_CTL, 13,
- "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
- "gpio_13", NULL, "hsusb1_tll_clk", NULL),
- _OMAP3_MUXENTRY(ETK_D0, 14,
- "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
- "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL),
- _OMAP3_MUXENTRY(ETK_D1, 15,
- "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
- "gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL),
- _OMAP3_MUXENTRY(ETK_D10, 24,
- "etk_d10", NULL, "uart1_rx", "hsusb2_clk",
- "gpio_24", NULL, "hsusb2_tll_clk", NULL),
- _OMAP3_MUXENTRY(ETK_D11, 25,
- "etk_d11", NULL, NULL, "hsusb2_stp",
- "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL),
- _OMAP3_MUXENTRY(ETK_D12, 26,
- "etk_d12", NULL, NULL, "hsusb2_dir",
- "gpio_26", NULL, "hsusb2_tll_dir", NULL),
- _OMAP3_MUXENTRY(ETK_D13, 27,
- "etk_d13", NULL, NULL, "hsusb2_nxt",
- "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL),
- _OMAP3_MUXENTRY(ETK_D14, 28,
- "etk_d14", NULL, NULL, "hsusb2_data0",
- "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL),
- _OMAP3_MUXENTRY(ETK_D15, 29,
- "etk_d15", NULL, NULL, "hsusb2_data1",
- "gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL),
- _OMAP3_MUXENTRY(ETK_D2, 16,
- "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
- "gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL),
- _OMAP3_MUXENTRY(ETK_D3, 17,
- "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
- "gpio_17", NULL, "hsusb1_tll_data7", NULL),
- _OMAP3_MUXENTRY(ETK_D4, 18,
- "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
- "gpio_18", NULL, "hsusb1_tll_data4", NULL),
- _OMAP3_MUXENTRY(ETK_D5, 19,
- "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
- "gpio_19", NULL, "hsusb1_tll_data5", NULL),
- _OMAP3_MUXENTRY(ETK_D6, 20,
- "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
- "gpio_20", NULL, "hsusb1_tll_data6", NULL),
- _OMAP3_MUXENTRY(ETK_D7, 21,
- "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
- "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL),
- _OMAP3_MUXENTRY(ETK_D8, 22,
- "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
- "gpio_22", NULL, "hsusb1_tll_dir", NULL),
- _OMAP3_MUXENTRY(ETK_D9, 23,
- "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
- "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL),
- _OMAP3_MUXENTRY(MCBSP3_CLKX, 142,
- "mcbsp3_clkx", "uart2_tx", NULL, NULL,
- "gpio_142", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_DR, 141,
- "mcbsp3_dr", "uart2_rts", NULL, NULL,
- "gpio_141", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_DX, 140,
- "mcbsp3_dx", "uart2_cts", NULL, NULL,
- "gpio_140", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP3_FSX, 143,
- "mcbsp3_fsx", "uart2_rx", NULL, NULL,
- "gpio_143", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT5, 137,
- "sdmmc2_dat5", "sdmmc2_dir_dat1",
- "cam_global_reset", "sdmmc3_dat1",
- "gpio_137", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT6, 138,
- "sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2",
- "gpio_138", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC2_DAT7, 139,
- "sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3",
- "gpio_139", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_CTS, 150,
- "uart1_cts", NULL, NULL, NULL,
- "gpio_150", NULL, NULL, "safe_mode"),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap3_cus_subset NULL
-#endif
-
-/*
- * Balls for CUS package
- * 423-pin s-PBGA Package, 0.65mm Ball Pitch (Bottom)
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
- && defined(CONFIG_OMAP_PACKAGE_CUS)
-static struct omap_ball __initdata omap3_cus_ball[] = {
- _OMAP3_BALLENTRY(CAM_D0, "ab18", NULL),
- _OMAP3_BALLENTRY(CAM_D1, "ac18", NULL),
- _OMAP3_BALLENTRY(CAM_D10, "f21", NULL),
- _OMAP3_BALLENTRY(CAM_D11, "g21", NULL),
- _OMAP3_BALLENTRY(CAM_D2, "g19", NULL),
- _OMAP3_BALLENTRY(CAM_D3, "f19", NULL),
- _OMAP3_BALLENTRY(CAM_D4, "g20", NULL),
- _OMAP3_BALLENTRY(CAM_D5, "b21", NULL),
- _OMAP3_BALLENTRY(CAM_D6, "l24", NULL),
- _OMAP3_BALLENTRY(CAM_D7, "k24", NULL),
- _OMAP3_BALLENTRY(CAM_D8, "j23", NULL),
- _OMAP3_BALLENTRY(CAM_D9, "k23", NULL),
- _OMAP3_BALLENTRY(CAM_FLD, "h24", NULL),
- _OMAP3_BALLENTRY(CAM_HS, "a22", NULL),
- _OMAP3_BALLENTRY(CAM_PCLK, "j19", NULL),
- _OMAP3_BALLENTRY(CAM_STROBE, "j20", NULL),
- _OMAP3_BALLENTRY(CAM_VS, "e18", NULL),
- _OMAP3_BALLENTRY(CAM_WEN, "f18", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKA, "b22", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKB, "c22", NULL),
- _OMAP3_BALLENTRY(DSS_ACBIAS, "j21", NULL),
- _OMAP3_BALLENTRY(DSS_DATA0, "ac19", NULL),
- _OMAP3_BALLENTRY(DSS_DATA1, "ab19", NULL),
- _OMAP3_BALLENTRY(DSS_DATA10, "ac22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA11, "ac23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA12, "ab22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA13, "y22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA14, "w22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA15, "v22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA16, "j22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA17, "g23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA18, "g24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA19, "h23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA2, "ad20", NULL),
- _OMAP3_BALLENTRY(DSS_DATA20, "d23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA21, "k22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA22, "v21", NULL),
- _OMAP3_BALLENTRY(DSS_DATA23, "w21", NULL),
- _OMAP3_BALLENTRY(DSS_DATA3, "ac20", NULL),
- _OMAP3_BALLENTRY(DSS_DATA4, "ad21", NULL),
- _OMAP3_BALLENTRY(DSS_DATA5, "ac21", NULL),
- _OMAP3_BALLENTRY(DSS_DATA6, "d24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA7, "e23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA8, "e24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA9, "f23", NULL),
- _OMAP3_BALLENTRY(DSS_HSYNC, "e22", NULL),
- _OMAP3_BALLENTRY(DSS_PCLK, "g22", NULL),
- _OMAP3_BALLENTRY(DSS_VSYNC, "f22", NULL),
- _OMAP3_BALLENTRY(ETK_CLK, "ac1", NULL),
- _OMAP3_BALLENTRY(ETK_CTL, "ad3", NULL),
- _OMAP3_BALLENTRY(ETK_D0, "ad6", NULL),
- _OMAP3_BALLENTRY(ETK_D1, "ac6", NULL),
- _OMAP3_BALLENTRY(ETK_D10, "ac3", NULL),
- _OMAP3_BALLENTRY(ETK_D11, "ac9", NULL),
- _OMAP3_BALLENTRY(ETK_D12, "ac10", NULL),
- _OMAP3_BALLENTRY(ETK_D13, "ad11", NULL),
- _OMAP3_BALLENTRY(ETK_D14, "ac11", NULL),
- _OMAP3_BALLENTRY(ETK_D15, "ad12", NULL),
- _OMAP3_BALLENTRY(ETK_D2, "ac7", NULL),
- _OMAP3_BALLENTRY(ETK_D3, "ad8", NULL),
- _OMAP3_BALLENTRY(ETK_D4, "ac5", NULL),
- _OMAP3_BALLENTRY(ETK_D5, "ad2", NULL),
- _OMAP3_BALLENTRY(ETK_D6, "ac8", NULL),
- _OMAP3_BALLENTRY(ETK_D7, "ad9", NULL),
- _OMAP3_BALLENTRY(ETK_D8, "ac4", NULL),
- _OMAP3_BALLENTRY(ETK_D9, "ad5", NULL),
- _OMAP3_BALLENTRY(GPMC_A1, "k4", NULL),
- _OMAP3_BALLENTRY(GPMC_A10, "g2", NULL),
- _OMAP3_BALLENTRY(GPMC_A2, "k3", NULL),
- _OMAP3_BALLENTRY(GPMC_A3, "k2", NULL),
- _OMAP3_BALLENTRY(GPMC_A4, "j4", NULL),
- _OMAP3_BALLENTRY(GPMC_A5, "j3", NULL),
- _OMAP3_BALLENTRY(GPMC_A6, "j2", NULL),
- _OMAP3_BALLENTRY(GPMC_A7, "j1", NULL),
- _OMAP3_BALLENTRY(GPMC_A8, "h1", NULL),
- _OMAP3_BALLENTRY(GPMC_A9, "h2", NULL),
- _OMAP3_BALLENTRY(GPMC_CLK, "w2", NULL),
- _OMAP3_BALLENTRY(GPMC_D10, "u1", NULL),
- _OMAP3_BALLENTRY(GPMC_D11, "r3", NULL),
- _OMAP3_BALLENTRY(GPMC_D12, "t3", NULL),
- _OMAP3_BALLENTRY(GPMC_D13, "u2", NULL),
- _OMAP3_BALLENTRY(GPMC_D14, "v1", NULL),
- _OMAP3_BALLENTRY(GPMC_D15, "v2", NULL),
- _OMAP3_BALLENTRY(GPMC_D8, "r2", NULL),
- _OMAP3_BALLENTRY(GPMC_D9, "t2", NULL),
- _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k5", NULL),
- _OMAP3_BALLENTRY(GPMC_NBE1, "l1", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS3, "d2", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS4, "f4", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS5, "g5", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS6, "f3", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS7, "g4", NULL),
- _OMAP3_BALLENTRY(GPMC_NWP, "e1", NULL),
- _OMAP3_BALLENTRY(GPMC_WAIT3, "c2", NULL),
- _OMAP3_BALLENTRY(HDQ_SIO, "a24", NULL),
- _OMAP3_BALLENTRY(HSUSB0_CLK, "r21", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA0, "t24", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA1, "t23", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA2, "u24", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA3, "u23", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA4, "w24", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA5, "v23", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA6, "w23", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA7, "t22", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DIR, "p23", NULL),
- _OMAP3_BALLENTRY(HSUSB0_NXT, "r22", NULL),
- _OMAP3_BALLENTRY(HSUSB0_STP, "r23", NULL),
- _OMAP3_BALLENTRY(I2C2_SCL, "ac15", NULL),
- _OMAP3_BALLENTRY(I2C2_SDA, "ac14", NULL),
- _OMAP3_BALLENTRY(I2C3_SCL, "ac13", NULL),
- _OMAP3_BALLENTRY(I2C3_SDA, "ac12", NULL),
- _OMAP3_BALLENTRY(I2C4_SCL, "y16", NULL),
- _OMAP3_BALLENTRY(I2C4_SDA, "y15", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU0, "ac24", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU1, "ad24", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKR, "w19", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKX, "v18", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DR, "y18", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DX, "w18", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSR, "ab20", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSX, "aa19", NULL),
- _OMAP3_BALLENTRY(MCBSP2_CLKX, "t21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DR, "v19", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DX, "r20", NULL),
- _OMAP3_BALLENTRY(MCBSP2_FSX, "v20", NULL),
- _OMAP3_BALLENTRY(MCBSP3_CLKX, "w4", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DR, "v5", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DX, "v6", NULL),
- _OMAP3_BALLENTRY(MCBSP3_FSX, "v4", NULL),
- _OMAP3_BALLENTRY(MCBSP_CLKS, "aa18", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CLK, "t5", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS0, "t6", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS3, "r5", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SIMO, "r4", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SOMI, "t4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CLK, "n5", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS0, "m5", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS1, "m4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SIMO, "n4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SOMI, "n3", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CLK, "m23", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CMD, "l23", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT0, "m22", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT1, "m21", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT2, "m20", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT3, "n23", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT4, "n22", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT5, "n21", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT6, "n20", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT7, "p24", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CLK, "y1", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CMD, "ab5", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT0, "ab3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT1, "y3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT2, "w3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT3, "v3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT4, "ab2", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT5, "aa2", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT6, "y2", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT7, "aa1", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT0, "ab12", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT1, "ac16", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT2, "ad17", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT3, "ad18", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT4, "ac17", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT5, "ab16", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT6, "aa15", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT1, "y7", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT2, "aa6", NULL),
- _OMAP3_BALLENTRY(SYS_CLKREQ, "y13", NULL),
- _OMAP3_BALLENTRY(SYS_NIRQ, "w16", NULL),
- _OMAP3_BALLENTRY(SYS_NRESWARM, "y10", NULL),
- _OMAP3_BALLENTRY(SYS_OFF_MODE, "ad23", NULL),
- _OMAP3_BALLENTRY(UART1_CTS, "ac2", NULL),
- _OMAP3_BALLENTRY(UART1_RTS, "w6", NULL),
- _OMAP3_BALLENTRY(UART1_RX, "v7", NULL),
- _OMAP3_BALLENTRY(UART1_TX, "w7", NULL),
- _OMAP3_BALLENTRY(UART3_CTS_RCTX, "a23", NULL),
- _OMAP3_BALLENTRY(UART3_RTS_SD, "b23", NULL),
- _OMAP3_BALLENTRY(UART3_RX_IRRX, "b24", NULL),
- _OMAP3_BALLENTRY(UART3_TX_IRTX, "c23", NULL),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap3_cus_ball NULL
-#endif
-
-/*
- * Signals different on CBB package compared to superset
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB)
-static struct omap_mux __initdata omap3_cbb_subset[] = {
- _OMAP3_MUXENTRY(CAM_D10, 109,
- "cam_d10", NULL, NULL, NULL,
- "gpio_109", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D11, 110,
- "cam_d11", NULL, NULL, NULL,
- "gpio_110", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D2, 101,
- "cam_d2", NULL, NULL, NULL,
- "gpio_101", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D3, 102,
- "cam_d3", NULL, NULL, NULL,
- "gpio_102", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D4, 103,
- "cam_d4", NULL, NULL, NULL,
- "gpio_103", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D5, 104,
- "cam_d5", NULL, NULL, NULL,
- "gpio_104", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_FLD, 98,
- "cam_fld", NULL, "cam_global_reset", NULL,
- "gpio_98", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_HS, 94,
- "cam_hs", NULL, NULL, NULL,
- "gpio_94", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_PCLK, 97,
- "cam_pclk", NULL, NULL, NULL,
- "gpio_97", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_STROBE, 126,
- "cam_strobe", NULL, NULL, NULL,
- "gpio_126", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_VS, 95,
- "cam_vs", NULL, NULL, NULL,
- "gpio_95", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_WEN, 167,
- "cam_wen", NULL, "cam_shutter", NULL,
- "gpio_167", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA6, 76,
- "dss_data6", NULL, "uart1_tx", NULL,
- "gpio_76", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA7, 77,
- "dss_data7", NULL, "uart1_rx", NULL,
- "gpio_77", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA8, 78,
- "dss_data8", NULL, NULL, NULL,
- "gpio_78", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA9, 79,
- "dss_data9", NULL, NULL, NULL,
- "gpio_79", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_HSYNC, 67,
- "dss_hsync", NULL, NULL, NULL,
- "gpio_67", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_PCLK, 66,
- "dss_pclk", NULL, NULL, NULL,
- "gpio_66", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(ETK_CLK, 12,
- "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
- "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL),
- _OMAP3_MUXENTRY(ETK_CTL, 13,
- "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
- "gpio_13", NULL, "hsusb1_tll_clk", NULL),
- _OMAP3_MUXENTRY(ETK_D0, 14,
- "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
- "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL),
- _OMAP3_MUXENTRY(ETK_D1, 15,
- "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
- "gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL),
- _OMAP3_MUXENTRY(ETK_D10, 24,
- "etk_d10", NULL, "uart1_rx", "hsusb2_clk",
- "gpio_24", NULL, "hsusb2_tll_clk", NULL),
- _OMAP3_MUXENTRY(ETK_D11, 25,
- "etk_d11", NULL, NULL, "hsusb2_stp",
- "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL),
- _OMAP3_MUXENTRY(ETK_D12, 26,
- "etk_d12", NULL, NULL, "hsusb2_dir",
- "gpio_26", NULL, "hsusb2_tll_dir", NULL),
- _OMAP3_MUXENTRY(ETK_D13, 27,
- "etk_d13", NULL, NULL, "hsusb2_nxt",
- "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL),
- _OMAP3_MUXENTRY(ETK_D14, 28,
- "etk_d14", NULL, NULL, "hsusb2_data0",
- "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL),
- _OMAP3_MUXENTRY(ETK_D15, 29,
- "etk_d15", NULL, NULL, "hsusb2_data1",
- "gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL),
- _OMAP3_MUXENTRY(ETK_D2, 16,
- "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
- "gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL),
- _OMAP3_MUXENTRY(ETK_D3, 17,
- "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
- "gpio_17", NULL, "hsusb1_tll_data7", NULL),
- _OMAP3_MUXENTRY(ETK_D4, 18,
- "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
- "gpio_18", NULL, "hsusb1_tll_data4", NULL),
- _OMAP3_MUXENTRY(ETK_D5, 19,
- "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
- "gpio_19", NULL, "hsusb1_tll_data5", NULL),
- _OMAP3_MUXENTRY(ETK_D6, 20,
- "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
- "gpio_20", NULL, "hsusb1_tll_data6", NULL),
- _OMAP3_MUXENTRY(ETK_D7, 21,
- "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
- "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL),
- _OMAP3_MUXENTRY(ETK_D8, 22,
- "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
- "gpio_22", NULL, "hsusb1_tll_dir", NULL),
- _OMAP3_MUXENTRY(ETK_D9, 23,
- "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
- "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap3_cbb_subset NULL
-#endif
-
-/*
- * Balls for CBB package
- * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom)
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
- && defined(CONFIG_OMAP_PACKAGE_CBB)
-static struct omap_ball __initdata omap3_cbb_ball[] = {
- _OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
- _OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
- _OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
- _OMAP3_BALLENTRY(CAM_D11, "c26", NULL),
- _OMAP3_BALLENTRY(CAM_D2, "b24", NULL),
- _OMAP3_BALLENTRY(CAM_D3, "c24", NULL),
- _OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
- _OMAP3_BALLENTRY(CAM_D5, "a25", NULL),
- _OMAP3_BALLENTRY(CAM_D6, "k28", NULL),
- _OMAP3_BALLENTRY(CAM_D7, "l28", NULL),
- _OMAP3_BALLENTRY(CAM_D8, "k27", NULL),
- _OMAP3_BALLENTRY(CAM_D9, "l27", NULL),
- _OMAP3_BALLENTRY(CAM_FLD, "c23", NULL),
- _OMAP3_BALLENTRY(CAM_HS, "a24", NULL),
- _OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL),
- _OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL),
- _OMAP3_BALLENTRY(CAM_VS, "a23", NULL),
- _OMAP3_BALLENTRY(CAM_WEN, "b23", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL),
- _OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL),
- _OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL),
- _OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL),
- _OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL),
- _OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL),
- _OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL),
- _OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL),
- _OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL),
- _OMAP3_BALLENTRY(ETK_CLK, "af10", NULL),
- _OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL),
- _OMAP3_BALLENTRY(ETK_D0, "af11", NULL),
- _OMAP3_BALLENTRY(ETK_D1, "ag12", NULL),
- _OMAP3_BALLENTRY(ETK_D10, "ae7", NULL),
- _OMAP3_BALLENTRY(ETK_D11, "af7", NULL),
- _OMAP3_BALLENTRY(ETK_D12, "ag7", NULL),
- _OMAP3_BALLENTRY(ETK_D13, "ah7", NULL),
- _OMAP3_BALLENTRY(ETK_D14, "ag8", NULL),
- _OMAP3_BALLENTRY(ETK_D15, "ah8", NULL),
- _OMAP3_BALLENTRY(ETK_D2, "ah12", NULL),
- _OMAP3_BALLENTRY(ETK_D3, "ae13", NULL),
- _OMAP3_BALLENTRY(ETK_D4, "ae11", NULL),
- _OMAP3_BALLENTRY(ETK_D5, "ah9", NULL),
- _OMAP3_BALLENTRY(ETK_D6, "af13", NULL),
- _OMAP3_BALLENTRY(ETK_D7, "ah14", NULL),
- _OMAP3_BALLENTRY(ETK_D8, "af9", NULL),
- _OMAP3_BALLENTRY(ETK_D9, "ag9", NULL),
- _OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"),
- _OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"),
- _OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"),
- _OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"),
- _OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"),
- _OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"),
- _OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"),
- _OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"),
- _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"),
- _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"),
- _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"),
- _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"),
- _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"),
- _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"),
- _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"),
- _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"),
- _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"),
- _OMAP3_BALLENTRY(GPMC_D8, "h2", "ab3"),
- _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"),
- _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"),
- _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"),
- _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL),
- _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"),
- _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"),
- _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL),
- _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL),
- _OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL),
- _OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL),
- _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL),
- _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL),
- _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL),
- _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL),
- _OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL),
- _OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL),
- _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL),
- _OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL),
- _OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL),
- _OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL),
- _OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL),
- _OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL),
- _OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL),
- _OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL),
- _OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT4, "p27", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT5, "p26", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT6, "r27", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT7, "r25", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL),
- _OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL),
- _OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL),
- _OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL),
- _OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL),
- _OMAP3_BALLENTRY(UART1_CTS, "w8", NULL),
- _OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL),
- _OMAP3_BALLENTRY(UART1_RX, "y8", NULL),
- _OMAP3_BALLENTRY(UART1_TX, "aa8", NULL),
- _OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL),
- _OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL),
- _OMAP3_BALLENTRY(UART2_RX, "ad25", NULL),
- _OMAP3_BALLENTRY(UART2_TX, "aa25", NULL),
- _OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL),
- _OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL),
- _OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL),
- _OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap3_cbb_ball NULL
-#endif
-
-/*
- * Signals different on 36XX CBP package compared to 34XX CBC package
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP)
-static struct omap_mux __initdata omap36xx_cbp_subset[] = {
- _OMAP3_MUXENTRY(CAM_D0, 99,
- "cam_d0", NULL, "csi2_dx2", NULL,
- "gpio_99", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D1, 100,
- "cam_d1", NULL, "csi2_dy2", NULL,
- "gpio_100", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D10, 109,
- "cam_d10", "ssi2_wake", NULL, NULL,
- "gpio_109", "hw_dbg8", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D2, 101,
- "cam_d2", "ssi2_rdy_tx", NULL, NULL,
- "gpio_101", "hw_dbg4", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D3, 102,
- "cam_d3", "ssi2_dat_rx", NULL, NULL,
- "gpio_102", "hw_dbg5", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D4, 103,
- "cam_d4", "ssi2_flag_rx", NULL, NULL,
- "gpio_103", "hw_dbg6", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_D5, 104,
- "cam_d5", "ssi2_rdy_rx", NULL, NULL,
- "gpio_104", "hw_dbg7", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_HS, 94,
- "cam_hs", "ssi2_dat_tx", NULL, NULL,
- "gpio_94", "hw_dbg0", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(CAM_VS, 95,
- "cam_vs", "ssi2_flag_tx", NULL, NULL,
- "gpio_95", "hw_dbg1", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA0, 70,
- "dss_data0", "dsi_dx0", "uart1_cts", NULL,
- "gpio_70", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA1, 71,
- "dss_data1", "dsi_dy0", "uart1_rts", NULL,
- "gpio_71", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA2, 72,
- "dss_data2", "dsi_dx1", NULL, NULL,
- "gpio_72", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA3, 73,
- "dss_data3", "dsi_dy1", NULL, NULL,
- "gpio_73", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA4, 74,
- "dss_data4", "dsi_dx2", "uart3_rx_irrx", NULL,
- "gpio_74", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA5, 75,
- "dss_data5", "dsi_dy2", "uart3_tx_irtx", NULL,
- "gpio_75", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA6, 76,
- "dss_data6", NULL, "uart1_tx", "dssvenc656_data6",
- "gpio_76", "hw_dbg14", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA7, 77,
- "dss_data7", NULL, "uart1_rx", "dssvenc656_data7",
- "gpio_77", "hw_dbg15", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA8, 78,
- "dss_data8", NULL, "uart3_rx_irrx", NULL,
- "gpio_78", "hw_dbg16", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(DSS_DATA9, 79,
- "dss_data9", NULL, "uart3_tx_irtx", NULL,
- "gpio_79", "hw_dbg17", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(ETK_D12, 26,
- "etk_d12", "sys_drm_msecure", NULL, "hsusb2_dir",
- "gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"),
- _OMAP3_MUXENTRY(GPMC_A11, 0,
- "gpmc_a11", NULL, NULL, NULL,
- NULL, NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_WAIT2, 64,
- "gpmc_wait2", NULL, "uart4_tx", NULL,
- "gpio_64", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(GPMC_WAIT3, 65,
- "gpmc_wait3", "sys_ndmareq1", "uart4_rx", NULL,
- "gpio_65", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA0, 125,
- "hsusb0_data0", NULL, "uart3_tx_irtx", NULL,
- "gpio_125", "uart2_tx", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA1, 130,
- "hsusb0_data1", NULL, "uart3_rx_irrx", NULL,
- "gpio_130", "uart2_rx", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA2, 131,
- "hsusb0_data2", NULL, "uart3_rts_sd", NULL,
- "gpio_131", "uart2_rts", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(HSUSB0_DATA3, 169,
- "hsusb0_data3", NULL, "uart3_cts_rctx", NULL,
- "gpio_169", "uart2_cts", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_CLKR, 156,
- "mcbsp1_clkr", "mcspi4_clk", "sim_cd", NULL,
- "gpio_156", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP1_FSR, 157,
- "mcbsp1_fsr", "adpllv2d_dithering_en1",
- "cam_global_reset", NULL,
- "gpio_157", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_CLKX, 152,
- "mcbsp4_clkx", "ssi1_dat_rx", NULL, NULL,
- "gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_DR, 153,
- "mcbsp4_dr", "ssi1_flag_rx", NULL, NULL,
- "gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_DX, 154,
- "mcbsp4_dx", "ssi1_rdy_rx", NULL, NULL,
- "gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"),
- _OMAP3_MUXENTRY(MCBSP4_FSX, 155,
- "mcbsp4_fsx", "ssi1_wake", NULL, NULL,
- "gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"),
- _OMAP3_MUXENTRY(MCSPI1_CS1, 175,
- "mcspi1_cs1", "adpllv2d_dithering_en2", NULL, "sdmmc3_cmd",
- "gpio_175", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0,
- "sad2d_mbusflag", "mad2d_sbusflag", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD28, 0,
- "sad2d_mcad28", "mad2d_mcad28", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD29, 0,
- "sad2d_mcad29", "mad2d_mcad29", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD32, 0,
- "sad2d_mcad32", "mad2d_mcad32", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD33, 0,
- "sad2d_mcad33", "mad2d_mcad33", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD34, 0,
- "sad2d_mcad34", "mad2d_mcad34", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD35, 0,
- "sad2d_mcad35", "mad2d_mcad35", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MCAD36, 0,
- "sad2d_mcad36", "mad2d_mcad36", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MREAD, 0,
- "sad2d_mread", "mad2d_sread", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_MWRITE, 0,
- "sad2d_mwrite", "mad2d_swrite", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0,
- "sad2d_sbusflag", "mad2d_mbusflag", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_SREAD, 0,
- "sad2d_sread", "mad2d_mread", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SAD2D_SWRITE, 0,
- "sad2d_swrite", "mad2d_mwrite", NULL, NULL,
- NULL, NULL, NULL, NULL),
- _OMAP3_MUXENTRY(SDMMC1_CLK, 120,
- "sdmmc1_clk", "ms_clk", NULL, NULL,
- "gpio_120", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_CMD, 121,
- "sdmmc1_cmd", "ms_bs", NULL, NULL,
- "gpio_121", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT0, 122,
- "sdmmc1_dat0", "ms_dat0", NULL, NULL,
- "gpio_122", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT1, 123,
- "sdmmc1_dat1", "ms_dat1", NULL, NULL,
- "gpio_123", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT2, 124,
- "sdmmc1_dat2", "ms_dat2", NULL, NULL,
- "gpio_124", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDMMC1_DAT3, 125,
- "sdmmc1_dat3", "ms_dat3", NULL, NULL,
- "gpio_125", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SDRC_CKE0, 0,
- "sdrc_cke0", NULL, NULL, NULL,
- NULL, NULL, NULL, "safe_mode_out1"),
- _OMAP3_MUXENTRY(SDRC_CKE1, 0,
- "sdrc_cke1", NULL, NULL, NULL,
- NULL, NULL, NULL, "safe_mode_out1"),
- _OMAP3_MUXENTRY(SIM_IO, 126,
- "sim_io", "sim_io_low_impedance", NULL, NULL,
- "gpio_126", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SIM_CLK, 127,
- "sim_clk", NULL, NULL, NULL,
- "gpio_127", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SIM_PWRCTRL, 128,
- "sim_pwrctrl", NULL, NULL, NULL,
- "gpio_128", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SIM_RST, 129,
- "sim_rst", NULL, NULL, NULL,
- "gpio_129", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT0, 2,
- "sys_boot0", NULL, NULL, "dss_data18",
- "gpio_2", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT1, 3,
- "sys_boot1", NULL, NULL, "dss_data19",
- "gpio_3", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT3, 5,
- "sys_boot3", NULL, NULL, "dss_data20",
- "gpio_5", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT4, 6,
- "sys_boot4", "sdmmc2_dir_dat2", NULL, "dss_data21",
- "gpio_6", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT5, 7,
- "sys_boot5", "sdmmc2_dir_dat3", NULL, "dss_data22",
- "gpio_7", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(SYS_BOOT6, 8,
- "sys_boot6", NULL, NULL, "dss_data23",
- "gpio_8", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_CTS, 150,
- "uart1_cts", "ssi1_rdy_tx", NULL, NULL,
- "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_RTS, 149,
- "uart1_rts", "ssi1_flag_tx", NULL, NULL,
- "gpio_149", NULL, NULL, "safe_mode"),
- _OMAP3_MUXENTRY(UART1_TX, 148,
- "uart1_tx", "ssi1_dat_tx", NULL, NULL,
- "gpio_148", NULL, NULL, "safe_mode"),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap36xx_cbp_subset NULL
-#endif
-
-/*
- * Balls for 36XX CBP package
- * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom)
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
- && defined (CONFIG_OMAP_PACKAGE_CBP)
-static struct omap_ball __initdata omap36xx_cbp_ball[] = {
- _OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
- _OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
- _OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
- _OMAP3_BALLENTRY(CAM_D11, "c26", NULL),
- _OMAP3_BALLENTRY(CAM_D2, "b24", NULL),
- _OMAP3_BALLENTRY(CAM_D3, "c24", NULL),
- _OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
- _OMAP3_BALLENTRY(CAM_D5, "a25", NULL),
- _OMAP3_BALLENTRY(CAM_D6, "k28", NULL),
- _OMAP3_BALLENTRY(CAM_D7, "l28", NULL),
- _OMAP3_BALLENTRY(CAM_D8, "k27", NULL),
- _OMAP3_BALLENTRY(CAM_D9, "l27", NULL),
- _OMAP3_BALLENTRY(CAM_FLD, "c23", NULL),
- _OMAP3_BALLENTRY(CAM_HS, "a24", NULL),
- _OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL),
- _OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL),
- _OMAP3_BALLENTRY(CAM_VS, "a23", NULL),
- _OMAP3_BALLENTRY(CAM_WEN, "b23", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
- _OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL),
- _OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL),
- _OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL),
- _OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL),
- _OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL),
- _OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL),
- _OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL),
- _OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL),
- _OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL),
- _OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL),
- _OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL),
- _OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL),
- _OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL),
- _OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL),
- _OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL),
- _OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL),
- _OMAP3_BALLENTRY(ETK_CLK, "af10", NULL),
- _OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL),
- _OMAP3_BALLENTRY(ETK_D0, "af11", NULL),
- _OMAP3_BALLENTRY(ETK_D1, "ag12", NULL),
- _OMAP3_BALLENTRY(ETK_D10, "ae7", NULL),
- _OMAP3_BALLENTRY(ETK_D11, "af7", NULL),
- _OMAP3_BALLENTRY(ETK_D12, "ag7", NULL),
- _OMAP3_BALLENTRY(ETK_D13, "ah7", NULL),
- _OMAP3_BALLENTRY(ETK_D14, "ag8", NULL),
- _OMAP3_BALLENTRY(ETK_D15, "ah8", NULL),
- _OMAP3_BALLENTRY(ETK_D2, "ah12", NULL),
- _OMAP3_BALLENTRY(ETK_D3, "ae13", NULL),
- _OMAP3_BALLENTRY(ETK_D4, "ae11", NULL),
- _OMAP3_BALLENTRY(ETK_D5, "ah9", NULL),
- _OMAP3_BALLENTRY(ETK_D6, "af13", NULL),
- _OMAP3_BALLENTRY(ETK_D7, "ah14", NULL),
- _OMAP3_BALLENTRY(ETK_D8, "af9", NULL),
- _OMAP3_BALLENTRY(ETK_D9, "ag9", NULL),
- _OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"),
- _OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"),
- _OMAP3_BALLENTRY(GPMC_A11, NULL, "ac20"),
- _OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"),
- _OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"),
- _OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"),
- _OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"),
- _OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"),
- _OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"),
- _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"),
- _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"),
- _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"),
- _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"),
- _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"),
- _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"),
- _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"),
- _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"),
- _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"),
- _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"),
- _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"),
- _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"),
- _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL),
- _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL),
- _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"),
- _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"),
- _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL),
- _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL),
- _OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL),
- _OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL),
- _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL),
- _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL),
- _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL),
- _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL),
- _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL),
- _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL),
- _OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL),
- _OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL),
- _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL),
- _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL),
- _OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL),
- _OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL),
- _OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL),
- _OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL),
- _OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL),
- _OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL),
- _OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL),
- _OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL),
- _OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL),
- _OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL),
- _OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL),
- _OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL),
- _OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL),
- _OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL),
- _OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL),
- _OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL),
- _OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL),
- _OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL),
- _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL),
- _OMAP3_BALLENTRY(SDRC_CKE0, "h16", "j22"),
- _OMAP3_BALLENTRY(SDRC_CKE1, "h17", "j23"),
- _OMAP3_BALLENTRY(SIM_CLK, "p26", NULL),
- _OMAP3_BALLENTRY(SIM_IO, "p27", NULL),
- _OMAP3_BALLENTRY(SIM_PWRCTRL, "r27", NULL),
- _OMAP3_BALLENTRY(SIM_RST, "r25", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL),
- _OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL),
- _OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL),
- _OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL),
- _OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL),
- _OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL),
- _OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL),
- _OMAP3_BALLENTRY(UART1_CTS, "w8", NULL),
- _OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL),
- _OMAP3_BALLENTRY(UART1_RX, "y8", NULL),
- _OMAP3_BALLENTRY(UART1_TX, "aa8", NULL),
- _OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL),
- _OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL),
- _OMAP3_BALLENTRY(UART2_RX, "ad25", NULL),
- _OMAP3_BALLENTRY(UART2_TX, "aa25", NULL),
- _OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL),
- _OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL),
- _OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL),
- _OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap36xx_cbp_ball NULL
-#endif
-
-int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
-{
- struct omap_mux *package_subset;
- struct omap_ball *package_balls;
-
- switch (flags & OMAP_PACKAGE_MASK) {
- case OMAP_PACKAGE_CBC:
- package_subset = omap3_cbc_subset;
- package_balls = omap3_cbc_ball;
- break;
- case OMAP_PACKAGE_CBB:
- package_subset = omap3_cbb_subset;
- package_balls = omap3_cbb_ball;
- break;
- case OMAP_PACKAGE_CUS:
- package_subset = omap3_cus_subset;
- package_balls = omap3_cus_ball;
- break;
- case OMAP_PACKAGE_CBP:
- package_subset = omap36xx_cbp_subset;
- package_balls = omap36xx_cbp_ball;
- break;
- default:
- pr_err("%s Unknown omap package, mux disabled\n", __func__);
- return -EINVAL;
- }
-
- return omap_mux_init("core", OMAP_MUX_GPIO_IN_MODE4,
- OMAP3_CONTROL_PADCONF_MUX_PBASE,
- OMAP3_CONTROL_PADCONF_MUX_SIZE,
- omap3_muxmodes, package_subset, board_subset,
- package_balls);
-}
diff --git a/arch/arm/mach-omap2/mux34xx.h b/arch/arm/mach-omap2/mux34xx.h
deleted file mode 100644
index 3f26d297c082..000000000000
--- a/arch/arm/mach-omap2/mux34xx.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2009 Nokia
- * Copyright (C) 2009 Texas Instruments
- *
- * 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 OMAP3_CONTROL_PADCONF_MUX_PBASE 0x48002030LU
-
-#define OMAP3_MUX(mode0, mux_value) \
-{ \
- .reg_offset = (OMAP3_CONTROL_PADCONF_##mode0##_OFFSET), \
- .value = (mux_value), \
-}
-
-/*
- * OMAP3 CONTROL_PADCONF* register offsets for pin-muxing
- *
- * Extracted from the TRM. Add 0x48002030 to these values to get the
- * absolute addresses. The name in the macro is the mode-0 name of
- * the pin. NOTE: These registers are 16-bits wide.
- *
- * Note that 34XX TRM uses MMC instead of SDMMC and SAD2D instead
- * of CHASSIS for some registers. For the defines, we follow the
- * 36XX naming, and use SDMMC and CHASSIS.
- */
-#define OMAP3_CONTROL_PADCONF_SDRC_D0_OFFSET 0x000
-#define OMAP3_CONTROL_PADCONF_SDRC_D1_OFFSET 0x002
-#define OMAP3_CONTROL_PADCONF_SDRC_D2_OFFSET 0x004
-#define OMAP3_CONTROL_PADCONF_SDRC_D3_OFFSET 0x006
-#define OMAP3_CONTROL_PADCONF_SDRC_D4_OFFSET 0x008
-#define OMAP3_CONTROL_PADCONF_SDRC_D5_OFFSET 0x00a
-#define OMAP3_CONTROL_PADCONF_SDRC_D6_OFFSET 0x00c
-#define OMAP3_CONTROL_PADCONF_SDRC_D7_OFFSET 0x00e
-#define OMAP3_CONTROL_PADCONF_SDRC_D8_OFFSET 0x010
-#define OMAP3_CONTROL_PADCONF_SDRC_D9_OFFSET 0x012
-#define OMAP3_CONTROL_PADCONF_SDRC_D10_OFFSET 0x014
-#define OMAP3_CONTROL_PADCONF_SDRC_D11_OFFSET 0x016
-#define OMAP3_CONTROL_PADCONF_SDRC_D12_OFFSET 0x018
-#define OMAP3_CONTROL_PADCONF_SDRC_D13_OFFSET 0x01a
-#define OMAP3_CONTROL_PADCONF_SDRC_D14_OFFSET 0x01c
-#define OMAP3_CONTROL_PADCONF_SDRC_D15_OFFSET 0x01e
-#define OMAP3_CONTROL_PADCONF_SDRC_D16_OFFSET 0x020
-#define OMAP3_CONTROL_PADCONF_SDRC_D17_OFFSET 0x022
-#define OMAP3_CONTROL_PADCONF_SDRC_D18_OFFSET 0x024
-#define OMAP3_CONTROL_PADCONF_SDRC_D19_OFFSET 0x026
-#define OMAP3_CONTROL_PADCONF_SDRC_D20_OFFSET 0x028
-#define OMAP3_CONTROL_PADCONF_SDRC_D21_OFFSET 0x02a
-#define OMAP3_CONTROL_PADCONF_SDRC_D22_OFFSET 0x02c
-#define OMAP3_CONTROL_PADCONF_SDRC_D23_OFFSET 0x02e
-#define OMAP3_CONTROL_PADCONF_SDRC_D24_OFFSET 0x030
-#define OMAP3_CONTROL_PADCONF_SDRC_D25_OFFSET 0x032
-#define OMAP3_CONTROL_PADCONF_SDRC_D26_OFFSET 0x034
-#define OMAP3_CONTROL_PADCONF_SDRC_D27_OFFSET 0x036
-#define OMAP3_CONTROL_PADCONF_SDRC_D28_OFFSET 0x038
-#define OMAP3_CONTROL_PADCONF_SDRC_D29_OFFSET 0x03a
-#define OMAP3_CONTROL_PADCONF_SDRC_D30_OFFSET 0x03c
-#define OMAP3_CONTROL_PADCONF_SDRC_D31_OFFSET 0x03e
-#define OMAP3_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x040
-#define OMAP3_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x042
-#define OMAP3_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x044
-#define OMAP3_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x046
-#define OMAP3_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x048
-#define OMAP3_CONTROL_PADCONF_GPMC_A1_OFFSET 0x04a
-#define OMAP3_CONTROL_PADCONF_GPMC_A2_OFFSET 0x04c
-#define OMAP3_CONTROL_PADCONF_GPMC_A3_OFFSET 0x04e
-#define OMAP3_CONTROL_PADCONF_GPMC_A4_OFFSET 0x050
-#define OMAP3_CONTROL_PADCONF_GPMC_A5_OFFSET 0x052
-#define OMAP3_CONTROL_PADCONF_GPMC_A6_OFFSET 0x054
-#define OMAP3_CONTROL_PADCONF_GPMC_A7_OFFSET 0x056
-#define OMAP3_CONTROL_PADCONF_GPMC_A8_OFFSET 0x058
-#define OMAP3_CONTROL_PADCONF_GPMC_A9_OFFSET 0x05a
-#define OMAP3_CONTROL_PADCONF_GPMC_A10_OFFSET 0x05c
-#define OMAP3_CONTROL_PADCONF_GPMC_D0_OFFSET 0x05e
-#define OMAP3_CONTROL_PADCONF_GPMC_D1_OFFSET 0x060
-#define OMAP3_CONTROL_PADCONF_GPMC_D2_OFFSET 0x062
-#define OMAP3_CONTROL_PADCONF_GPMC_D3_OFFSET 0x064
-#define OMAP3_CONTROL_PADCONF_GPMC_D4_OFFSET 0x066
-#define OMAP3_CONTROL_PADCONF_GPMC_D5_OFFSET 0x068
-#define OMAP3_CONTROL_PADCONF_GPMC_D6_OFFSET 0x06a
-#define OMAP3_CONTROL_PADCONF_GPMC_D7_OFFSET 0x06c
-#define OMAP3_CONTROL_PADCONF_GPMC_D8_OFFSET 0x06e
-#define OMAP3_CONTROL_PADCONF_GPMC_D9_OFFSET 0x070
-#define OMAP3_CONTROL_PADCONF_GPMC_D10_OFFSET 0x072
-#define OMAP3_CONTROL_PADCONF_GPMC_D11_OFFSET 0x074
-#define OMAP3_CONTROL_PADCONF_GPMC_D12_OFFSET 0x076
-#define OMAP3_CONTROL_PADCONF_GPMC_D13_OFFSET 0x078
-#define OMAP3_CONTROL_PADCONF_GPMC_D14_OFFSET 0x07a
-#define OMAP3_CONTROL_PADCONF_GPMC_D15_OFFSET 0x07c
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x07e
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x080
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x082
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x084
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x086
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x088
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x08a
-#define OMAP3_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x08c
-#define OMAP3_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x08e
-#define OMAP3_CONTROL_PADCONF_GPMC_NADV_ALE_OFFSET 0x090
-#define OMAP3_CONTROL_PADCONF_GPMC_NOE_OFFSET 0x092
-#define OMAP3_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x094
-#define OMAP3_CONTROL_PADCONF_GPMC_NBE0_CLE_OFFSET 0x096
-#define OMAP3_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x098
-#define OMAP3_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x09a
-#define OMAP3_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x09c
-#define OMAP3_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x09e
-#define OMAP3_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x0a0
-#define OMAP3_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x0a2
-#define OMAP3_CONTROL_PADCONF_DSS_PCLK_OFFSET 0x0a4
-#define OMAP3_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x0a6
-#define OMAP3_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x0a8
-#define OMAP3_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x0aa
-#define OMAP3_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x0ac
-#define OMAP3_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x0ae
-#define OMAP3_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x0b0
-#define OMAP3_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x0b2
-#define OMAP3_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x0b4
-#define OMAP3_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x0b6
-#define OMAP3_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x0b8
-#define OMAP3_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x0ba
-#define OMAP3_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x0bc
-#define OMAP3_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x0be
-#define OMAP3_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x0c0
-#define OMAP3_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x0c2
-#define OMAP3_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x0c4
-#define OMAP3_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x0c6
-#define OMAP3_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x0c8
-#define OMAP3_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x0ca
-#define OMAP3_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x0cc
-#define OMAP3_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x0ce
-#define OMAP3_CONTROL_PADCONF_DSS_DATA18_OFFSET 0x0d0
-#define OMAP3_CONTROL_PADCONF_DSS_DATA19_OFFSET 0x0d2
-#define OMAP3_CONTROL_PADCONF_DSS_DATA20_OFFSET 0x0d4
-#define OMAP3_CONTROL_PADCONF_DSS_DATA21_OFFSET 0x0d6
-#define OMAP3_CONTROL_PADCONF_DSS_DATA22_OFFSET 0x0d8
-#define OMAP3_CONTROL_PADCONF_DSS_DATA23_OFFSET 0x0da
-#define OMAP3_CONTROL_PADCONF_CAM_HS_OFFSET 0x0dc
-#define OMAP3_CONTROL_PADCONF_CAM_VS_OFFSET 0x0de
-#define OMAP3_CONTROL_PADCONF_CAM_XCLKA_OFFSET 0x0e0
-#define OMAP3_CONTROL_PADCONF_CAM_PCLK_OFFSET 0x0e2
-#define OMAP3_CONTROL_PADCONF_CAM_FLD_OFFSET 0x0e4
-#define OMAP3_CONTROL_PADCONF_CAM_D0_OFFSET 0x0e6
-#define OMAP3_CONTROL_PADCONF_CAM_D1_OFFSET 0x0e8
-#define OMAP3_CONTROL_PADCONF_CAM_D2_OFFSET 0x0ea
-#define OMAP3_CONTROL_PADCONF_CAM_D3_OFFSET 0x0ec
-#define OMAP3_CONTROL_PADCONF_CAM_D4_OFFSET 0x0ee
-#define OMAP3_CONTROL_PADCONF_CAM_D5_OFFSET 0x0f0
-#define OMAP3_CONTROL_PADCONF_CAM_D6_OFFSET 0x0f2
-#define OMAP3_CONTROL_PADCONF_CAM_D7_OFFSET 0x0f4
-#define OMAP3_CONTROL_PADCONF_CAM_D8_OFFSET 0x0f6
-#define OMAP3_CONTROL_PADCONF_CAM_D9_OFFSET 0x0f8
-#define OMAP3_CONTROL_PADCONF_CAM_D10_OFFSET 0x0fa
-#define OMAP3_CONTROL_PADCONF_CAM_D11_OFFSET 0x0fc
-#define OMAP3_CONTROL_PADCONF_CAM_XCLKB_OFFSET 0x0fe
-#define OMAP3_CONTROL_PADCONF_CAM_WEN_OFFSET 0x100
-#define OMAP3_CONTROL_PADCONF_CAM_STROBE_OFFSET 0x102
-#define OMAP3_CONTROL_PADCONF_CSI2_DX0_OFFSET 0x104
-#define OMAP3_CONTROL_PADCONF_CSI2_DY0_OFFSET 0x106
-#define OMAP3_CONTROL_PADCONF_CSI2_DX1_OFFSET 0x108
-#define OMAP3_CONTROL_PADCONF_CSI2_DY1_OFFSET 0x10a
-#define OMAP3_CONTROL_PADCONF_MCBSP2_FSX_OFFSET 0x10c
-#define OMAP3_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x10e
-#define OMAP3_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x110
-#define OMAP3_CONTROL_PADCONF_MCBSP2_DX_OFFSET 0x112
-#define OMAP3_CONTROL_PADCONF_SDMMC1_CLK_OFFSET 0x114
-#define OMAP3_CONTROL_PADCONF_SDMMC1_CMD_OFFSET 0x116
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT0_OFFSET 0x118
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT1_OFFSET 0x11a
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT2_OFFSET 0x11c
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT3_OFFSET 0x11e
-
-/* SDMMC1_DAT4 - DAT7 are SIM_IO SIM_CLK SIM_PWRCTRL and SIM_RST on 36xx */
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT4_OFFSET 0x120
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT5_OFFSET 0x122
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT6_OFFSET 0x124
-#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT7_OFFSET 0x126
-
-#define OMAP3_CONTROL_PADCONF_SDMMC2_CLK_OFFSET 0x128
-#define OMAP3_CONTROL_PADCONF_SDMMC2_CMD_OFFSET 0x12a
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT0_OFFSET 0x12c
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT1_OFFSET 0x12e
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT2_OFFSET 0x130
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT3_OFFSET 0x132
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT4_OFFSET 0x134
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT5_OFFSET 0x136
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT6_OFFSET 0x138
-#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT7_OFFSET 0x13a
-#define OMAP3_CONTROL_PADCONF_MCBSP3_DX_OFFSET 0x13c
-#define OMAP3_CONTROL_PADCONF_MCBSP3_DR_OFFSET 0x13e
-#define OMAP3_CONTROL_PADCONF_MCBSP3_CLKX_OFFSET 0x140
-#define OMAP3_CONTROL_PADCONF_MCBSP3_FSX_OFFSET 0x142
-#define OMAP3_CONTROL_PADCONF_UART2_CTS_OFFSET 0x144
-#define OMAP3_CONTROL_PADCONF_UART2_RTS_OFFSET 0x146
-#define OMAP3_CONTROL_PADCONF_UART2_TX_OFFSET 0x148
-#define OMAP3_CONTROL_PADCONF_UART2_RX_OFFSET 0x14a
-#define OMAP3_CONTROL_PADCONF_UART1_TX_OFFSET 0x14c
-#define OMAP3_CONTROL_PADCONF_UART1_RTS_OFFSET 0x14e
-#define OMAP3_CONTROL_PADCONF_UART1_CTS_OFFSET 0x150
-#define OMAP3_CONTROL_PADCONF_UART1_RX_OFFSET 0x152
-#define OMAP3_CONTROL_PADCONF_MCBSP4_CLKX_OFFSET 0x154
-#define OMAP3_CONTROL_PADCONF_MCBSP4_DR_OFFSET 0x156
-#define OMAP3_CONTROL_PADCONF_MCBSP4_DX_OFFSET 0x158
-#define OMAP3_CONTROL_PADCONF_MCBSP4_FSX_OFFSET 0x15a
-#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x15c
-#define OMAP3_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x15e
-#define OMAP3_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x160
-#define OMAP3_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x162
-#define OMAP3_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x164
-#define OMAP3_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x166
-#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x168
-#define OMAP3_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x16a
-#define OMAP3_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x16c
-#define OMAP3_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x16e
-#define OMAP3_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x170
-#define OMAP3_CONTROL_PADCONF_HSUSB0_CLK_OFFSET 0x172
-#define OMAP3_CONTROL_PADCONF_HSUSB0_STP_OFFSET 0x174
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DIR_OFFSET 0x176
-#define OMAP3_CONTROL_PADCONF_HSUSB0_NXT_OFFSET 0x178
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA0_OFFSET 0x17a
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA1_OFFSET 0x17c
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA2_OFFSET 0x17e
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA3_OFFSET 0x180
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA4_OFFSET 0x182
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA5_OFFSET 0x184
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA6_OFFSET 0x186
-#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA7_OFFSET 0x188
-#define OMAP3_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x18a
-#define OMAP3_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x18c
-#define OMAP3_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x18e
-#define OMAP3_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x190
-#define OMAP3_CONTROL_PADCONF_I2C3_SCL_OFFSET 0x192
-#define OMAP3_CONTROL_PADCONF_I2C3_SDA_OFFSET 0x194
-#define OMAP3_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x196
-#define OMAP3_CONTROL_PADCONF_MCSPI1_CLK_OFFSET 0x198
-#define OMAP3_CONTROL_PADCONF_MCSPI1_SIMO_OFFSET 0x19a
-#define OMAP3_CONTROL_PADCONF_MCSPI1_SOMI_OFFSET 0x19c
-#define OMAP3_CONTROL_PADCONF_MCSPI1_CS0_OFFSET 0x19e
-#define OMAP3_CONTROL_PADCONF_MCSPI1_CS1_OFFSET 0x1a0
-#define OMAP3_CONTROL_PADCONF_MCSPI1_CS2_OFFSET 0x1a2
-#define OMAP3_CONTROL_PADCONF_MCSPI1_CS3_OFFSET 0x1a4
-#define OMAP3_CONTROL_PADCONF_MCSPI2_CLK_OFFSET 0x1a6
-#define OMAP3_CONTROL_PADCONF_MCSPI2_SIMO_OFFSET 0x1a8
-#define OMAP3_CONTROL_PADCONF_MCSPI2_SOMI_OFFSET 0x1aa
-#define OMAP3_CONTROL_PADCONF_MCSPI2_CS0_OFFSET 0x1ac
-#define OMAP3_CONTROL_PADCONF_MCSPI2_CS1_OFFSET 0x1ae
-#define OMAP3_CONTROL_PADCONF_SYS_NIRQ_OFFSET 0x1b0
-#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT2_OFFSET 0x1b2
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD0_OFFSET 0x1b4
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD1_OFFSET 0x1b6
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD2_OFFSET 0x1b8
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD3_OFFSET 0x1ba
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD4_OFFSET 0x1bc
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD5_OFFSET 0x1be
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD6_OFFSET 0x1c0
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD7_OFFSET 0x1c2
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD8_OFFSET 0x1c4
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD9_OFFSET 0x1c6
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD10_OFFSET 0x1c8
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD11_OFFSET 0x1ca
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD12_OFFSET 0x1cc
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD13_OFFSET 0x1ce
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD14_OFFSET 0x1d0
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD15_OFFSET 0x1d2
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD16_OFFSET 0x1d4
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD17_OFFSET 0x1d6
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD18_OFFSET 0x1d8
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD19_OFFSET 0x1da
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD20_OFFSET 0x1dc
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD21_OFFSET 0x1de
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD22_OFFSET 0x1e0
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD23_OFFSET 0x1e2
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD24_OFFSET 0x1e4
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD25_OFFSET 0x1e6
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD26_OFFSET 0x1e8
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD27_OFFSET 0x1ea
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD28_OFFSET 0x1ec
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD29_OFFSET 0x1ee
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD30_OFFSET 0x1f0
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD31_OFFSET 0x1f2
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD32_OFFSET 0x1f4
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD33_OFFSET 0x1f6
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD34_OFFSET 0x1f8
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD35_OFFSET 0x1fa
-#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD36_OFFSET 0x1fc
-
-/* Note that 34xx TRM has SAD2D instead of CHASSIS for these */
-#define OMAP3_CONTROL_PADCONF_CHASSIS_CLK26MI_OFFSET 0x1fe
-#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESPWRON_OFFSET 0x200
-#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESWARW_OFFSET 0x202
-#define OMAP3_CONTROL_PADCONF_CHASSIS_NIRQ_OFFSET 0x204
-#define OMAP3_CONTROL_PADCONF_CHASSIS_FIQ_OFFSET 0x206
-#define OMAP3_CONTROL_PADCONF_CHASSIS_ARMIRQ_OFFSET 0x208
-#define OMAP3_CONTROL_PADCONF_CHASSIS_IVAIRQ_OFFSET 0x20a
-#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ0_OFFSET 0x20c
-#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ1_OFFSET 0x20e
-#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ2_OFFSET 0x210
-#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ3_OFFSET 0x212
-#define OMAP3_CONTROL_PADCONF_CHASSIS_NTRST_OFFSET 0x214
-#define OMAP3_CONTROL_PADCONF_CHASSIS_TDI_OFFSET 0x216
-#define OMAP3_CONTROL_PADCONF_CHASSIS_TDO_OFFSET 0x218
-#define OMAP3_CONTROL_PADCONF_CHASSIS_TMS_OFFSET 0x21a
-#define OMAP3_CONTROL_PADCONF_CHASSIS_TCK_OFFSET 0x21c
-#define OMAP3_CONTROL_PADCONF_CHASSIS_RTCK_OFFSET 0x21e
-#define OMAP3_CONTROL_PADCONF_CHASSIS_MSTDBY_OFFSET 0x220
-#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEREQ_OFFSET 0x222
-#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEACK_OFFSET 0x224
-
-#define OMAP3_CONTROL_PADCONF_SAD2D_MWRITE_OFFSET 0x226
-#define OMAP3_CONTROL_PADCONF_SAD2D_SWRITE_OFFSET 0x228
-#define OMAP3_CONTROL_PADCONF_SAD2D_MREAD_OFFSET 0x22a
-#define OMAP3_CONTROL_PADCONF_SAD2D_SREAD_OFFSET 0x22c
-#define OMAP3_CONTROL_PADCONF_SAD2D_MBUSFLAG_OFFSET 0x22e
-#define OMAP3_CONTROL_PADCONF_SAD2D_SBUSFLAG_OFFSET 0x230
-#define OMAP3_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x232
-#define OMAP3_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x234
-
-/* 36xx only */
-#define OMAP3_CONTROL_PADCONF_GPMC_A11_OFFSET 0x236
-#define OMAP3_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x570
-#define OMAP3_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x572
-#define OMAP3_CONTROL_PADCONF_SDRC_A0_OFFSET 0x574
-#define OMAP3_CONTROL_PADCONF_SDRC_A1_OFFSET 0x576
-#define OMAP3_CONTROL_PADCONF_SDRC_A2_OFFSET 0x578
-#define OMAP3_CONTROL_PADCONF_SDRC_A3_OFFSET 0x57a
-#define OMAP3_CONTROL_PADCONF_SDRC_A4_OFFSET 0x57c
-#define OMAP3_CONTROL_PADCONF_SDRC_A5_OFFSET 0x57e
-#define OMAP3_CONTROL_PADCONF_SDRC_A6_OFFSET 0x580
-#define OMAP3_CONTROL_PADCONF_SDRC_A7_OFFSET 0x582
-#define OMAP3_CONTROL_PADCONF_SDRC_A8_OFFSET 0x584
-#define OMAP3_CONTROL_PADCONF_SDRC_A9_OFFSET 0x586
-#define OMAP3_CONTROL_PADCONF_SDRC_A10_OFFSET 0x588
-#define OMAP3_CONTROL_PADCONF_SDRC_A11_OFFSET 0x58a
-#define OMAP3_CONTROL_PADCONF_SDRC_A12_OFFSET 0x58c
-#define OMAP3_CONTROL_PADCONF_SDRC_A13_OFFSET 0x58e
-#define OMAP3_CONTROL_PADCONF_SDRC_A14_OFFSET 0x590
-#define OMAP3_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x592
-#define OMAP3_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x594
-#define OMAP3_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x596
-#define OMAP3_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x598
-#define OMAP3_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x59a
-#define OMAP3_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x59c
-#define OMAP3_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x59e
-#define OMAP3_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x5a0
-#define OMAP3_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x5a2
-#define OMAP3_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x5a4
-
-/* 36xx only, these are SDMMC1_DAT4 - DAT7 on 34xx */
-#define OMAP3_CONTROL_PADCONF_SIM_IO_OFFSET 0x120
-#define OMAP3_CONTROL_PADCONF_SIM_CLK_OFFSET 0x122
-#define OMAP3_CONTROL_PADCONF_SIM_PWRCTRL_OFFSET 0x124
-#define OMAP3_CONTROL_PADCONF_SIM_RST_OFFSET 0x126
-
-#define OMAP3_CONTROL_PADCONF_ETK_CLK_OFFSET 0x5a8
-#define OMAP3_CONTROL_PADCONF_ETK_CTL_OFFSET 0x5aa
-#define OMAP3_CONTROL_PADCONF_ETK_D0_OFFSET 0x5ac
-#define OMAP3_CONTROL_PADCONF_ETK_D1_OFFSET 0x5ae
-#define OMAP3_CONTROL_PADCONF_ETK_D2_OFFSET 0x5b0
-#define OMAP3_CONTROL_PADCONF_ETK_D3_OFFSET 0x5b2
-#define OMAP3_CONTROL_PADCONF_ETK_D4_OFFSET 0x5b4
-#define OMAP3_CONTROL_PADCONF_ETK_D5_OFFSET 0x5b6
-#define OMAP3_CONTROL_PADCONF_ETK_D6_OFFSET 0x5b8
-#define OMAP3_CONTROL_PADCONF_ETK_D7_OFFSET 0x5ba
-#define OMAP3_CONTROL_PADCONF_ETK_D8_OFFSET 0x5bc
-#define OMAP3_CONTROL_PADCONF_ETK_D9_OFFSET 0x5be
-#define OMAP3_CONTROL_PADCONF_ETK_D10_OFFSET 0x5c0
-#define OMAP3_CONTROL_PADCONF_ETK_D11_OFFSET 0x5c2
-#define OMAP3_CONTROL_PADCONF_ETK_D12_OFFSET 0x5c4
-#define OMAP3_CONTROL_PADCONF_ETK_D13_OFFSET 0x5c6
-#define OMAP3_CONTROL_PADCONF_ETK_D14_OFFSET 0x5c8
-#define OMAP3_CONTROL_PADCONF_ETK_D15_OFFSET 0x5ca
-#define OMAP3_CONTROL_PADCONF_I2C4_SCL_OFFSET 0x9d0
-#define OMAP3_CONTROL_PADCONF_I2C4_SDA_OFFSET 0x9d2
-#define OMAP3_CONTROL_PADCONF_SYS_32K_OFFSET 0x9d4
-#define OMAP3_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x9d6
-#define OMAP3_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x9d8
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT0_OFFSET 0x9da
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT1_OFFSET 0x9dc
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT2_OFFSET 0x9de
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT3_OFFSET 0x9e0
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT4_OFFSET 0x9e2
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT5_OFFSET 0x9e4
-#define OMAP3_CONTROL_PADCONF_SYS_BOOT6_OFFSET 0x9e6
-#define OMAP3_CONTROL_PADCONF_SYS_OFF_MODE_OFFSET 0x9e8
-#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT1_OFFSET 0x9ea
-#define OMAP3_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x9ec
-#define OMAP3_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x9ee
-#define OMAP3_CONTROL_PADCONF_JTAG_TMS_TMSC_OFFSET 0x9f0
-#define OMAP3_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x9f2
-#define OMAP3_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x9f4
-#define OMAP3_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x9f6
-#define OMAP3_CONTROL_PADCONF_SAD2D_SWAKEUP_OFFSET 0xa1c
-#define OMAP3_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0xa1e
-#define OMAP3_CONTROL_PADCONF_JTAG_TDO_OFFSET 0xa20
-#define OMAP3_CONTROL_PADCONF_GPIO_127 0xa24
-#define OMAP3_CONTROL_PADCONF_GPIO_126 0xa26
-#define OMAP3_CONTROL_PADCONF_GPIO_128 0xa28
-#define OMAP3_CONTROL_PADCONF_GPIO_129 0xa2a
-
-#define OMAP3_CONTROL_PADCONF_MUX_SIZE \
- (OMAP3_CONTROL_PADCONF_GPIO_129 + 0x2)
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index ad982465efd0..7d62ad48c7c9 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -48,6 +48,7 @@
#include <asm/smp_scu.h>
#include <asm/pgalloc.h>
#include <asm/suspend.h>
+#include <asm/virt.h>
#include <asm/hardware/cache-l2x0.h>
#include "soc.h"
@@ -244,10 +245,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
save_state = 1;
break;
case PWRDM_POWER_RET:
- if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
+ if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
save_state = 0;
- break;
- }
+ break;
default:
/*
* CPUx CSWR is invalid hardware state. Also CPUx OSWR
@@ -371,8 +371,12 @@ int __init omap4_mpuss_init(void)
pm_info = &per_cpu(omap4_pm_info, 0x0);
if (sar_base) {
pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
- pm_info->wkup_sar_addr = sar_base +
- CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+ if (cpu_is_omap44xx())
+ pm_info->wkup_sar_addr = sar_base +
+ CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+ else
+ pm_info->wkup_sar_addr = sar_base +
+ OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
}
pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
@@ -391,8 +395,12 @@ int __init omap4_mpuss_init(void)
pm_info = &per_cpu(omap4_pm_info, 0x1);
if (sar_base) {
pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
- pm_info->wkup_sar_addr = sar_base +
- CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+ if (cpu_is_omap44xx())
+ pm_info->wkup_sar_addr = sar_base +
+ CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+ else
+ pm_info->wkup_sar_addr = sar_base +
+ OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
}
@@ -453,15 +461,24 @@ void __init omap4_mpuss_early_init(void)
{
unsigned long startup_pa;
- if (!cpu_is_omap44xx())
+ if (!(cpu_is_omap44xx() || soc_is_omap54xx()))
return;
sar_base = omap4_get_sar_ram_base();
if (cpu_is_omap443x())
startup_pa = virt_to_phys(omap4_secondary_startup);
- else
+ else if (cpu_is_omap446x())
startup_pa = virt_to_phys(omap4460_secondary_startup);
+ else if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
+ startup_pa = virt_to_phys(omap5_secondary_hyp_startup);
+ else
+ startup_pa = virt_to_phys(omap5_secondary_startup);
- writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+ if (cpu_is_omap44xx())
+ writel_relaxed(startup_pa, sar_base +
+ CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+ else
+ writel_relaxed(startup_pa, sar_base +
+ OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
}
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 792b1069f724..5b2966a0f733 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -31,6 +31,8 @@
/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08
+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xe00
+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xe04
#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)
#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 1052b29697b8..759e1d45ba25 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -160,7 +160,6 @@
#include "prm44xx.h"
#include "prm33xx.h"
#include "prminst44xx.h"
-#include "mux.h"
#include "pm.h"
/* Name of the OMAP hwmod for the MPU */
@@ -217,9 +216,6 @@ static LIST_HEAD(omap_hwmod_list);
/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
static struct omap_hwmod *mpu_oh;
-/* io_chain_lock: used to serialize reconfigurations of the I/O chain */
-static DEFINE_SPINLOCK(io_chain_lock);
-
/*
* linkspace: ptr to a buffer that struct omap_hwmod_link records are
* allocated from - used to reduce the number of small memory
@@ -594,51 +590,6 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
}
/**
- * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
- * @oh: struct omap_hwmod *
- * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
- *
- * Set or clear the I/O pad wakeup flag in the mux entries for the
- * hwmod @oh. This function changes the @oh->mux->pads_dynamic array
- * in memory. If the hwmod is currently idled, and the new idle
- * values don't match the previous ones, this function will also
- * update the SCM PADCTRL registers. Otherwise, if the hwmod is not
- * currently idled, this function won't touch the hardware: the new
- * mux settings are written to the SCM PADCTRL registers when the
- * hwmod is idled. No return value.
- */
-static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
-{
- struct omap_device_pad *pad;
- bool change = false;
- u16 prev_idle;
- int j;
-
- if (!oh->mux || !oh->mux->enabled)
- return;
-
- for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
- pad = oh->mux->pads_dynamic[j];
-
- if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
- continue;
-
- prev_idle = pad->idle;
-
- if (set_wake)
- pad->idle |= OMAP_WAKEUP_EN;
- else
- pad->idle &= ~OMAP_WAKEUP_EN;
-
- if (prev_idle != pad->idle)
- change = true;
- }
-
- if (change && oh->_state == _HWMOD_STATE_IDLE)
- omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
-}
-
-/**
* _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
* @oh: struct omap_hwmod *
*
@@ -2018,29 +1969,6 @@ static int _reset(struct omap_hwmod *oh)
}
/**
- * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
- *
- * Call the appropriate PRM function to clear any logged I/O chain
- * wakeups and to reconfigure the chain. This apparently needs to be
- * done upon every mux change. Since hwmods can be concurrently
- * enabled and idled, hold a spinlock around the I/O chain
- * reconfiguration sequence. No return value.
- *
- * XXX When the PRM code is moved to drivers, this function can be removed,
- * as the PRM infrastructure should abstract this.
- */
-static void _reconfigure_io_chain(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&io_chain_lock, flags);
-
- omap_prm_reconfigure_io_chain();
-
- spin_unlock_irqrestore(&io_chain_lock, flags);
-}
-
-/**
* _omap4_update_context_lost - increment hwmod context loss counter if
* hwmod context was lost, and clear hardware context loss reg
* @oh: hwmod to check for context loss
@@ -2109,18 +2037,9 @@ static int _enable(struct omap_hwmod *oh)
/*
* hwmods with HWMOD_INIT_NO_IDLE flag set are left in enabled
- * state at init. Now that someone is really trying to enable
- * them, just ensure that the hwmod mux is set.
+ * state at init.
*/
if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
- /*
- * If the caller has mux data populated, do the mux'ing
- * which wouldn't have been done as part of the _enable()
- * done during setup.
- */
- if (oh->mux)
- omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
-
oh->_int_flags &= ~_HWMOD_SKIP_ENABLE;
return 0;
}
@@ -2145,16 +2064,6 @@ static int _enable(struct omap_hwmod *oh)
if (_are_all_hardreset_lines_asserted(oh))
return 0;
- /* Mux pins for device runtime if populated */
- if (oh->mux && (!oh->mux->enabled ||
- ((oh->_state == _HWMOD_STATE_IDLE) &&
- oh->mux->pads_dynamic))) {
- omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
- _reconfigure_io_chain();
- } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
- _reconfigure_io_chain();
- }
-
_add_initiator_dep(oh, mpu_oh);
if (oh->clkdm) {
@@ -2260,14 +2169,6 @@ static int _idle(struct omap_hwmod *oh)
clkdm_hwmod_disable(oh->clkdm, oh);
}
- /* Mux pins for device idle if populated */
- if (oh->mux && oh->mux->pads_dynamic) {
- omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
- _reconfigure_io_chain();
- } else if (oh->flags & HWMOD_RECONFIG_IO_CHAIN) {
- _reconfigure_io_chain();
- }
-
oh->_state = _HWMOD_STATE_IDLE;
return 0;
@@ -2334,10 +2235,6 @@ static int _shutdown(struct omap_hwmod *oh)
for (i = 0; i < oh->rst_lines_cnt; i++)
_assert_hardreset(oh, oh->rst_lines[i].name);
- /* Mux pins to safe mode or use populated off mode values */
- if (oh->mux)
- omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED);
-
oh->_state = _HWMOD_STATE_DISABLED;
return 0;
@@ -3729,7 +3626,6 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
_write_sysconfig(v, oh);
}
- _set_idle_ioring_wakeup(oh, true);
spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
@@ -3762,7 +3658,6 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
_write_sysconfig(v, oh);
}
- _set_idle_ioring_wakeup(oh, false);
spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c
index c1e98d589100..6d2e32462df9 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c
@@ -17,156 +17,11 @@
#include "omap_hwmod_common_data.h"
-struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = {
- {
- .pa_start = 0x4809c000,
- .pa_end = 0x4809c1ff,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = {
- {
- .pa_start = 0x480b4000,
- .pa_end = 0x480b41ff,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_i2c1_addr_space[] = {
- {
- .pa_start = 0x48070000,
- .pa_end = 0x48070000 + SZ_128 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_i2c2_addr_space[] = {
- {
- .pa_start = 0x48072000,
- .pa_end = 0x48072000 + SZ_128 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_dss_addrs[] = {
- {
- .pa_start = 0x48050000,
- .pa_end = 0x48050000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_dss_dispc_addrs[] = {
- {
- .pa_start = 0x48050400,
- .pa_end = 0x48050400 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_dss_rfbi_addrs[] = {
- {
- .pa_start = 0x48050800,
- .pa_end = 0x48050800 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_dss_venc_addrs[] = {
- {
- .pa_start = 0x48050C00,
- .pa_end = 0x48050C00 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_timer10_addrs[] = {
- {
- .pa_start = 0x48086000,
- .pa_end = 0x48086000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_timer11_addrs[] = {
- {
- .pa_start = 0x48088000,
- .pa_end = 0x48088000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2xxx_timer12_addrs[] = {
- {
- .pa_start = 0x4808a000,
- .pa_end = 0x4808a000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_mcspi1_addr_space[] = {
- {
- .pa_start = 0x48098000,
- .pa_end = 0x48098000 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_mcspi2_addr_space[] = {
- {
- .pa_start = 0x4809a000,
- .pa_end = 0x4809a000 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[] = {
- {
- .pa_start = 0x480b8000,
- .pa_end = 0x480b8000 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
struct omap_hwmod_addr_space omap2_dma_system_addrs[] = {
{
.pa_start = 0x48056000,
.pa_end = 0x48056000 + SZ_4K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_mcbsp1_addrs[] = {
- {
- .name = "mpu",
- .pa_start = 0x48074000,
- .pa_end = 0x480740ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
-struct omap_hwmod_addr_space omap2_hdq1w_addr_space[] = {
- {
- .pa_start = 0x480b2000,
- .pa_end = 0x480b2fff,
- .flags = ADDR_TYPE_RT,
+ .flags = ADDR_TYPE_RT,
},
- { }
+ { },
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
index c6c6384de867..cfaeb0f78cc8 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
@@ -45,204 +45,31 @@ struct omap_hwmod_class omap2_venc_hwmod_class = {
.name = "venc",
};
-
-/* Common DMA request line data */
-struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[] = {
- { .name = "rx", .dma_req = 50, },
- { .name = "tx", .dma_req = 49, },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_uart2_sdma_reqs[] = {
- { .name = "rx", .dma_req = 52, },
- { .name = "tx", .dma_req = 51, },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_uart3_sdma_reqs[] = {
- { .name = "rx", .dma_req = 54, },
- { .name = "tx", .dma_req = 53, },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_i2c1_sdma_reqs[] = {
- { .name = "tx", .dma_req = 27 },
- { .name = "rx", .dma_req = 28 },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_i2c2_sdma_reqs[] = {
- { .name = "tx", .dma_req = 29 },
- { .name = "rx", .dma_req = 30 },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_mcspi1_sdma_reqs[] = {
- { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */
- { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */
- { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */
- { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */
- { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */
- { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */
- { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */
- { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_mcspi2_sdma_reqs[] = {
- { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */
- { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */
- { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */
- { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_mcbsp1_sdma_reqs[] = {
- { .name = "rx", .dma_req = 32 },
- { .name = "tx", .dma_req = 31 },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_mcbsp2_sdma_reqs[] = {
- { .name = "rx", .dma_req = 34 },
- { .name = "tx", .dma_req = 33 },
- { .dma_req = -1 }
-};
-
-struct omap_hwmod_dma_info omap2_mcbsp3_sdma_reqs[] = {
- { .name = "rx", .dma_req = 18 },
- { .name = "tx", .dma_req = 17 },
- { .dma_req = -1 }
-};
-
-/* Other IP block data */
-
-
/*
* omap_hwmod class data
*/
struct omap_hwmod_class l3_hwmod_class = {
- .name = "l3"
+ .name = "l3",
};
struct omap_hwmod_class l4_hwmod_class = {
- .name = "l4"
+ .name = "l4",
};
struct omap_hwmod_class mpu_hwmod_class = {
- .name = "mpu"
+ .name = "mpu",
};
struct omap_hwmod_class iva_hwmod_class = {
- .name = "iva"
+ .name = "iva",
};
/* Common MPU IRQ line data */
-struct omap_hwmod_irq_info omap2_timer1_mpu_irqs[] = {
- { .irq = 37 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer2_mpu_irqs[] = {
- { .irq = 38 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer3_mpu_irqs[] = {
- { .irq = 39 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer4_mpu_irqs[] = {
- { .irq = 40 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer5_mpu_irqs[] = {
- { .irq = 41 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer6_mpu_irqs[] = {
- { .irq = 42 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer7_mpu_irqs[] = {
- { .irq = 43 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer8_mpu_irqs[] = {
- { .irq = 44 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer9_mpu_irqs[] = {
- { .irq = 45 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer10_mpu_irqs[] = {
- { .irq = 46 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_timer11_mpu_irqs[] = {
- { .irq = 47 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_uart1_mpu_irqs[] = {
- { .irq = 72 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_uart2_mpu_irqs[] = {
- { .irq = 73 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[] = {
- { .irq = 74 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
struct omap_hwmod_irq_info omap2_dispc_irqs[] = {
{ .irq = 25 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[] = {
- { .irq = 56 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[] = {
- { .irq = 57 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_gpio1_irqs[] = {
- { .irq = 29 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK1 */
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_gpio2_irqs[] = {
- { .irq = 30 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK2 */
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_gpio3_irqs[] = {
- { .irq = 31 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK3 */
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_gpio4_irqs[] = {
- { .irq = 32 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK4 */
- { .irq = -1 },
+ { .irq = -1, },
};
struct omap_hwmod_irq_info omap2_dma_system_irqs[] = {
@@ -250,17 +77,7 @@ struct omap_hwmod_irq_info omap2_dma_system_irqs[] = {
{ .name = "1", .irq = 13 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ1 */
{ .name = "2", .irq = 14 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ2 */
{ .name = "3", .irq = 15 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ3 */
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[] = {
- { .irq = 65 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
-struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[] = {
- { .irq = 66 + OMAP_INTC_START, },
- { .irq = -1 },
+ { .irq = -1, },
};
struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc = {
@@ -277,9 +94,3 @@ struct omap_hwmod_class omap2_hdq1w_class = {
.sysc = &omap2_hdq1w_sysc,
.reset = &omap_hdq1w_reset,
};
-
-struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[] = {
- { .irq = 58 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
index 656861c29d5c..9b30b6b471ae 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
@@ -191,7 +191,6 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__dss = {
.master = &omap2xxx_l4_core_hwmod,
.slave = &omap2xxx_dss_core_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION,
@@ -206,7 +205,6 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_dispc = {
.master = &omap2xxx_l4_core_hwmod,
.slave = &omap2xxx_dss_dispc_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_dispc_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP2420_L4_CORE_FW_DSS_DISPC_REGION,
@@ -221,7 +219,6 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_rfbi = {
.master = &omap2xxx_l4_core_hwmod,
.slave = &omap2xxx_dss_rfbi_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_rfbi_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION,
@@ -236,7 +233,6 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc = {
.master = &omap2xxx_l4_core_hwmod,
.slave = &omap2xxx_dss_venc_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_venc_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP2420_L4_CORE_FW_DSS_VENC_REGION,
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 36bcd2e75422..e047033caa3e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -569,7 +569,6 @@ struct omap_hwmod omap2xxx_dss_core_hwmod = {
struct omap_hwmod omap2xxx_dss_dispc_hwmod = {
.name = "dss_dispc",
.class = &omap2_dispc_hwmod_class,
- .mpu_irqs = omap2_dispc_irqs,
.main_clk = "dss1_fck",
.prcm = {
.omap2 = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
index d3e61d1a02d7..434bd1a77229 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
@@ -68,6 +68,7 @@ extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart6;
extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc;
extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0;
extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0;
+extern struct omap_hwmod_ocp_if am33xx_l4_per__rng;
extern struct omap_hwmod am33xx_l3_main_hwmod;
extern struct omap_hwmod am33xx_l3_s_hwmod;
@@ -80,6 +81,7 @@ extern struct omap_hwmod am33xx_gfx_hwmod;
extern struct omap_hwmod am33xx_prcm_hwmod;
extern struct omap_hwmod am33xx_aes0_hwmod;
extern struct omap_hwmod am33xx_sha0_hwmod;
+extern struct omap_hwmod am33xx_rng_hwmod;
extern struct omap_hwmod am33xx_ocmcram_hwmod;
extern struct omap_hwmod am33xx_smartreflex0_hwmod;
extern struct omap_hwmod am33xx_smartreflex1_hwmod;
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
index 10dff2f0086a..8236e5c49ec3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
@@ -547,3 +547,11 @@ struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = {
.addr = am33xx_aes0_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+
+/* l4 per -> rng */
+struct omap_hwmod_ocp_if am33xx_l4_per__rng = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_rng_hwmod,
+ .clk = "rng_fck",
+ .user = OCP_USER_MPU,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
index e2d84aa7f595..de06a1d5ffab 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -268,6 +268,33 @@ struct omap_hwmod am33xx_sha0_hwmod = {
},
};
+/* rng */
+static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = {
+ .rev_offs = 0x1fe0,
+ .sysc_offs = 0x1fe4,
+ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class am33xx_rng_hwmod_class = {
+ .name = "rng",
+ .sysc = &am33xx_rng_sysc,
+};
+
+struct omap_hwmod am33xx_rng_hwmod = {
+ .name = "rng",
+ .class = &am33xx_rng_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "rng_fck",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
/* ocmcram */
static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
.name = "ocmcram",
@@ -1315,6 +1342,7 @@ static void omap_hwmod_am33xx_clkctrl(void)
CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET);
CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_rng_hwmod, AM33XX_CM_PER_RNG_CLKCTRL_OFFSET);
}
static void omap_hwmod_am33xx_rst(void)
@@ -1388,6 +1416,7 @@ static void omap_hwmod_am43xx_clkctrl(void)
CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET);
CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET);
+ CLKCTRL(am33xx_rng_hwmod, AM43XX_CM_PER_RNG_CLKCTRL_OFFSET);
}
static void omap_hwmod_am43xx_rst(void)
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index e1c2025d6d3e..6dc51a774a26 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -503,41 +503,6 @@ static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
.flags = OCPIF_SWSUP_IDLE,
};
-/* rng */
-static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = {
- .rev_offs = 0x1fe0,
- .sysc_offs = 0x1fe4,
- .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
- .idlemodes = SIDLE_FORCE | SIDLE_NO,
- .sysc_fields = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_rng_hwmod_class = {
- .name = "rng",
- .sysc = &am33xx_rng_sysc,
-};
-
-static struct omap_hwmod am33xx_rng_hwmod = {
- .name = "rng",
- .class = &am33xx_rng_hwmod_class,
- .clkdm_name = "l4ls_clkdm",
- .flags = HWMOD_SWSUP_SIDLE,
- .main_clk = "rng_fck",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
-};
-
-static struct omap_hwmod_ocp_if am33xx_l4_per__rng = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_rng_hwmod,
- .clk = "rng_fck",
- .user = OCP_USER_MPU,
-};
-
static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l3_main__emif,
&am33xx_mpu__l3_main,
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 1cc4a6f3954e..56f917ec8621 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -53,16 +53,10 @@
*/
/* L3 */
-static struct omap_hwmod_irq_info omap3xxx_l3_main_irqs[] = {
- { .irq = 9 + OMAP_INTC_START, },
- { .irq = 10 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_l3_main_hwmod = {
.name = "l3_main",
.class = &l3_hwmod_class,
- .mpu_irqs = omap3xxx_l3_main_irqs,
.flags = HWMOD_NO_IDLEST,
};
@@ -95,14 +89,9 @@ static struct omap_hwmod omap3xxx_l4_sec_hwmod = {
};
/* MPU */
-static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = {
- { .name = "pmu", .irq = 3 + OMAP_INTC_START },
- { .irq = -1 }
-};
static struct omap_hwmod omap3xxx_mpu_hwmod = {
.name = "mpu",
- .mpu_irqs = omap3xxx_mpu_irqs,
.class = &mpu_hwmod_class,
.main_clk = "arm_fck",
};
@@ -128,7 +117,7 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {
.module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
.idlest_reg_id = 1,
.idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
- }
+ },
},
};
@@ -197,7 +186,6 @@ static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
/* timer1 */
static struct omap_hwmod omap3xxx_timer1_hwmod = {
.name = "timer1",
- .mpu_irqs = omap2_timer1_mpu_irqs,
.main_clk = "gpt1_fck",
.prcm = {
.omap2 = {
@@ -216,7 +204,6 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
/* timer2 */
static struct omap_hwmod omap3xxx_timer2_hwmod = {
.name = "timer2",
- .mpu_irqs = omap2_timer2_mpu_irqs,
.main_clk = "gpt2_fck",
.prcm = {
.omap2 = {
@@ -234,7 +221,6 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {
/* timer3 */
static struct omap_hwmod omap3xxx_timer3_hwmod = {
.name = "timer3",
- .mpu_irqs = omap2_timer3_mpu_irqs,
.main_clk = "gpt3_fck",
.prcm = {
.omap2 = {
@@ -252,7 +238,6 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {
/* timer4 */
static struct omap_hwmod omap3xxx_timer4_hwmod = {
.name = "timer4",
- .mpu_irqs = omap2_timer4_mpu_irqs,
.main_clk = "gpt4_fck",
.prcm = {
.omap2 = {
@@ -270,7 +255,6 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {
/* timer5 */
static struct omap_hwmod omap3xxx_timer5_hwmod = {
.name = "timer5",
- .mpu_irqs = omap2_timer5_mpu_irqs,
.main_clk = "gpt5_fck",
.prcm = {
.omap2 = {
@@ -289,7 +273,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
/* timer6 */
static struct omap_hwmod omap3xxx_timer6_hwmod = {
.name = "timer6",
- .mpu_irqs = omap2_timer6_mpu_irqs,
.main_clk = "gpt6_fck",
.prcm = {
.omap2 = {
@@ -308,7 +291,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
/* timer7 */
static struct omap_hwmod omap3xxx_timer7_hwmod = {
.name = "timer7",
- .mpu_irqs = omap2_timer7_mpu_irqs,
.main_clk = "gpt7_fck",
.prcm = {
.omap2 = {
@@ -327,7 +309,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
/* timer8 */
static struct omap_hwmod omap3xxx_timer8_hwmod = {
.name = "timer8",
- .mpu_irqs = omap2_timer8_mpu_irqs,
.main_clk = "gpt8_fck",
.prcm = {
.omap2 = {
@@ -346,7 +327,6 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = {
/* timer9 */
static struct omap_hwmod omap3xxx_timer9_hwmod = {
.name = "timer9",
- .mpu_irqs = omap2_timer9_mpu_irqs,
.main_clk = "gpt9_fck",
.prcm = {
.omap2 = {
@@ -365,7 +345,6 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = {
/* timer10 */
static struct omap_hwmod omap3xxx_timer10_hwmod = {
.name = "timer10",
- .mpu_irqs = omap2_timer10_mpu_irqs,
.main_clk = "gpt10_fck",
.prcm = {
.omap2 = {
@@ -384,7 +363,6 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
/* timer11 */
static struct omap_hwmod omap3xxx_timer11_hwmod = {
.name = "timer11",
- .mpu_irqs = omap2_timer11_mpu_irqs,
.main_clk = "gpt11_fck",
.prcm = {
.omap2 = {
@@ -401,14 +379,9 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = {
};
/* timer12 */
-static struct omap_hwmod_irq_info omap3xxx_timer12_mpu_irqs[] = {
- { .irq = 95 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_timer12_hwmod = {
.name = "timer12",
- .mpu_irqs = omap3xxx_timer12_mpu_irqs,
.main_clk = "gpt12_fck",
.prcm = {
.omap2 = {
@@ -485,8 +458,6 @@ static struct omap_hwmod omap3xxx_wd_timer2_hwmod = {
/* UART1 */
static struct omap_hwmod omap3xxx_uart1_hwmod = {
.name = "uart1",
- .mpu_irqs = omap2_uart1_mpu_irqs,
- .sdma_reqs = omap2_uart1_sdma_reqs,
.main_clk = "uart1_fck",
.flags = DEBUG_TI81XXUART1_FLAGS | HWMOD_SWSUP_SIDLE,
.prcm = {
@@ -504,8 +475,6 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = {
/* UART2 */
static struct omap_hwmod omap3xxx_uart2_hwmod = {
.name = "uart2",
- .mpu_irqs = omap2_uart2_mpu_irqs,
- .sdma_reqs = omap2_uart2_sdma_reqs,
.main_clk = "uart2_fck",
.flags = DEBUG_TI81XXUART2_FLAGS | HWMOD_SWSUP_SIDLE,
.prcm = {
@@ -523,8 +492,6 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = {
/* UART3 */
static struct omap_hwmod omap3xxx_uart3_hwmod = {
.name = "uart3",
- .mpu_irqs = omap2_uart3_mpu_irqs,
- .sdma_reqs = omap2_uart3_sdma_reqs,
.main_clk = "uart3_fck",
.flags = DEBUG_OMAP3UART3_FLAGS | DEBUG_TI81XXUART3_FLAGS |
HWMOD_SWSUP_SIDLE,
@@ -541,21 +508,10 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = {
};
/* UART4 */
-static struct omap_hwmod_irq_info uart4_mpu_irqs[] = {
- { .irq = 80 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info uart4_sdma_reqs[] = {
- { .name = "rx", .dma_req = 82, },
- { .name = "tx", .dma_req = 81, },
- { .dma_req = -1 }
-};
static struct omap_hwmod omap36xx_uart4_hwmod = {
.name = "uart4",
- .mpu_irqs = uart4_mpu_irqs,
- .sdma_reqs = uart4_sdma_reqs,
.main_clk = "uart4_fck",
.flags = DEBUG_OMAP3UART4_FLAGS | HWMOD_SWSUP_SIDLE,
.prcm = {
@@ -570,16 +526,7 @@ static struct omap_hwmod omap36xx_uart4_hwmod = {
.class = &omap2_uart_class,
};
-static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = {
- { .irq = 84 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = {
- { .name = "rx", .dma_req = 55, },
- { .name = "tx", .dma_req = 54, },
- { .dma_req = -1 }
-};
/*
* XXX AM35xx UART4 cannot complete its softreset without uart1_fck or
@@ -597,8 +544,6 @@ static struct omap_hwmod_opt_clk am35xx_uart4_opt_clks[] = {
static struct omap_hwmod am35xx_uart4_hwmod = {
.name = "uart4",
- .mpu_irqs = am35xx_uart4_mpu_irqs,
- .sdma_reqs = am35xx_uart4_sdma_reqs,
.main_clk = "uart4_fck",
.prcm = {
.omap2 = {
@@ -625,7 +570,7 @@ static struct omap_hwmod_class i2c_class = {
static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = {
{ .name = "dispc", .dma_req = 5 },
{ .name = "dsi1", .dma_req = 74 },
- { .dma_req = -1 }
+ { .dma_req = -1, },
};
/* dss */
@@ -714,7 +659,7 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
},
},
.flags = HWMOD_NO_IDLEST,
- .dev_attr = &omap2_3_dss_dispc_dev_attr
+ .dev_attr = &omap2_3_dss_dispc_dev_attr,
};
/*
@@ -738,11 +683,6 @@ static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
.sysc = &omap3xxx_dsi_sysc,
};
-static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
- { .irq = 25 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-
/* dss_dsi1 */
static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = {
{ .role = "sys_clk", .clk = "dss2_alwon_fck" },
@@ -751,7 +691,6 @@ static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = {
static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
.name = "dss_dsi1",
.class = &omap3xxx_dsi_hwmod_class,
- .mpu_irqs = omap3xxx_dsi1_irqs,
.main_clk = "dss1_alwon_fck",
.prcm = {
.omap2 = {
@@ -815,8 +754,6 @@ static struct omap_i2c_dev_attr i2c1_dev_attr = {
static struct omap_hwmod omap3xxx_i2c1_hwmod = {
.name = "i2c1",
.flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
- .mpu_irqs = omap2_i2c1_mpu_irqs,
- .sdma_reqs = omap2_i2c1_sdma_reqs,
.main_clk = "i2c1_fck",
.prcm = {
.omap2 = {
@@ -840,8 +777,6 @@ static struct omap_i2c_dev_attr i2c2_dev_attr = {
static struct omap_hwmod omap3xxx_i2c2_hwmod = {
.name = "i2c2",
.flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
- .mpu_irqs = omap2_i2c2_mpu_irqs,
- .sdma_reqs = omap2_i2c2_sdma_reqs,
.main_clk = "i2c2_fck",
.prcm = {
.omap2 = {
@@ -862,22 +797,11 @@ static struct omap_i2c_dev_attr i2c3_dev_attr = {
.flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
};
-static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = {
- { .irq = 61 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = {
- { .name = "tx", .dma_req = 25 },
- { .name = "rx", .dma_req = 26 },
- { .dma_req = -1 }
-};
static struct omap_hwmod omap3xxx_i2c3_hwmod = {
.name = "i2c3",
.flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
- .mpu_irqs = i2c3_mpu_irqs,
- .sdma_reqs = i2c3_sdma_reqs,
.main_clk = "i2c3_fck",
.prcm = {
.omap2 = {
@@ -928,7 +852,6 @@ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
static struct omap_hwmod omap3xxx_gpio1_hwmod = {
.name = "gpio1",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
- .mpu_irqs = omap2_gpio1_irqs,
.main_clk = "gpio1_ick",
.opt_clks = gpio1_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
@@ -953,7 +876,6 @@ static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
static struct omap_hwmod omap3xxx_gpio2_hwmod = {
.name = "gpio2",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
- .mpu_irqs = omap2_gpio2_irqs,
.main_clk = "gpio2_ick",
.opt_clks = gpio2_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
@@ -978,7 +900,6 @@ static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
static struct omap_hwmod omap3xxx_gpio3_hwmod = {
.name = "gpio3",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
- .mpu_irqs = omap2_gpio3_irqs,
.main_clk = "gpio3_ick",
.opt_clks = gpio3_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
@@ -1003,7 +924,6 @@ static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
static struct omap_hwmod omap3xxx_gpio4_hwmod = {
.name = "gpio4",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
- .mpu_irqs = omap2_gpio4_irqs,
.main_clk = "gpio4_ick",
.opt_clks = gpio4_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
@@ -1021,10 +941,6 @@ static struct omap_hwmod omap3xxx_gpio4_hwmod = {
};
/* gpio5 */
-static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = {
- { .irq = 33 + OMAP_INTC_START, }, /* INT_34XX_GPIO_BANK5 */
- { .irq = -1 },
-};
static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
{ .role = "dbclk", .clk = "gpio5_dbck", },
@@ -1033,7 +949,6 @@ static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
static struct omap_hwmod omap3xxx_gpio5_hwmod = {
.name = "gpio5",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
- .mpu_irqs = omap3xxx_gpio5_irqs,
.main_clk = "gpio5_ick",
.opt_clks = gpio5_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
@@ -1051,10 +966,6 @@ static struct omap_hwmod omap3xxx_gpio5_hwmod = {
};
/* gpio6 */
-static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = {
- { .irq = 34 + OMAP_INTC_START, }, /* INT_34XX_GPIO_BANK6 */
- { .irq = -1 },
-};
static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
{ .role = "dbclk", .clk = "gpio6_dbck", },
@@ -1063,7 +974,6 @@ static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
static struct omap_hwmod omap3xxx_gpio6_hwmod = {
.name = "gpio6",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
- .mpu_irqs = omap3xxx_gpio6_irqs,
.main_clk = "gpio6_ick",
.opt_clks = gpio6_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
@@ -1156,18 +1066,10 @@ static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = {
};
/* mcbsp1 */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = {
- { .name = "common", .irq = 16 + OMAP_INTC_START, },
- { .name = "tx", .irq = 59 + OMAP_INTC_START, },
- { .name = "rx", .irq = 60 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
.name = "mcbsp1",
.class = &omap3xxx_mcbsp_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp1_irqs,
- .sdma_reqs = omap2_mcbsp1_sdma_reqs,
.main_clk = "mcbsp1_fck",
.prcm = {
.omap2 = {
@@ -1183,12 +1085,6 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
};
/* mcbsp2 */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = {
- { .name = "common", .irq = 17 + OMAP_INTC_START, },
- { .name = "tx", .irq = 62 + OMAP_INTC_START, },
- { .name = "rx", .irq = 63 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
.sidetone = "mcbsp2_sidetone",
@@ -1197,8 +1093,6 @@ static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
.name = "mcbsp2",
.class = &omap3xxx_mcbsp_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp2_irqs,
- .sdma_reqs = omap2_mcbsp2_sdma_reqs,
.main_clk = "mcbsp2_fck",
.prcm = {
.omap2 = {
@@ -1215,12 +1109,6 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
};
/* mcbsp3 */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = {
- { .name = "common", .irq = 22 + OMAP_INTC_START, },
- { .name = "tx", .irq = 89 + OMAP_INTC_START, },
- { .name = "rx", .irq = 90 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = {
.sidetone = "mcbsp3_sidetone",
@@ -1229,8 +1117,6 @@ static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = {
static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
.name = "mcbsp3",
.class = &omap3xxx_mcbsp_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp3_irqs,
- .sdma_reqs = omap2_mcbsp3_sdma_reqs,
.main_clk = "mcbsp3_fck",
.prcm = {
.omap2 = {
@@ -1247,24 +1133,11 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
};
/* mcbsp4 */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = {
- { .name = "common", .irq = 23 + OMAP_INTC_START, },
- { .name = "tx", .irq = 54 + OMAP_INTC_START, },
- { .name = "rx", .irq = 55 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap3xxx_mcbsp4_sdma_chs[] = {
- { .name = "rx", .dma_req = 20 },
- { .name = "tx", .dma_req = 19 },
- { .dma_req = -1 }
-};
static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
.name = "mcbsp4",
.class = &omap3xxx_mcbsp_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp4_irqs,
- .sdma_reqs = omap3xxx_mcbsp4_sdma_chs,
.main_clk = "mcbsp4_fck",
.prcm = {
.omap2 = {
@@ -1280,24 +1153,11 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
};
/* mcbsp5 */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = {
- { .name = "common", .irq = 27 + OMAP_INTC_START, },
- { .name = "tx", .irq = 81 + OMAP_INTC_START, },
- { .name = "rx", .irq = 82 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap3xxx_mcbsp5_sdma_chs[] = {
- { .name = "rx", .dma_req = 22 },
- { .name = "tx", .dma_req = 21 },
- { .dma_req = -1 }
-};
static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
.name = "mcbsp5",
.class = &omap3xxx_mcbsp_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp5_irqs,
- .sdma_reqs = omap3xxx_mcbsp5_sdma_chs,
.main_clk = "mcbsp5_fck",
.prcm = {
.omap2 = {
@@ -1325,29 +1185,19 @@ static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = {
};
/* mcbsp2_sidetone */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp2_sidetone_irqs[] = {
- { .name = "irq", .irq = 4 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
.name = "mcbsp2_sidetone",
.class = &omap3xxx_mcbsp_sidetone_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs,
.main_clk = "mcbsp2_ick",
.flags = HWMOD_NO_IDLEST,
};
/* mcbsp3_sidetone */
-static struct omap_hwmod_irq_info omap3xxx_mcbsp3_sidetone_irqs[] = {
- { .name = "irq", .irq = 5 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
.name = "mcbsp3_sidetone",
.class = &omap3xxx_mcbsp_sidetone_hwmod_class,
- .mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs,
.main_clk = "mcbsp3_ick",
.flags = HWMOD_NO_IDLEST,
};
@@ -1394,10 +1244,6 @@ static struct omap_smartreflex_dev_attr sr1_dev_attr = {
.sensor_voltdm_name = "mpu_iva",
};
-static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
- { .irq = 18 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap34xx_sr1_hwmod = {
.name = "smartreflex_mpu_iva",
@@ -1413,7 +1259,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
},
},
.dev_attr = &sr1_dev_attr,
- .mpu_irqs = omap3_smartreflex_mpu_irqs,
.flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
@@ -1431,7 +1276,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
},
},
.dev_attr = &sr1_dev_attr,
- .mpu_irqs = omap3_smartreflex_mpu_irqs,
};
/* SR2 */
@@ -1439,10 +1283,6 @@ static struct omap_smartreflex_dev_attr sr2_dev_attr = {
.sensor_voltdm_name = "core",
};
-static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
- { .irq = 19 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap34xx_sr2_hwmod = {
.name = "smartreflex_core",
@@ -1458,7 +1298,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
},
},
.dev_attr = &sr2_dev_attr,
- .mpu_irqs = omap3_smartreflex_core_irqs,
.flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
@@ -1476,7 +1315,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
},
},
.dev_attr = &sr2_dev_attr,
- .mpu_irqs = omap3_smartreflex_core_irqs,
};
/*
@@ -1545,8 +1383,6 @@ static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
static struct omap_hwmod omap34xx_mcspi1 = {
.name = "mcspi1",
- .mpu_irqs = omap2_mcspi1_mpu_irqs,
- .sdma_reqs = omap2_mcspi1_sdma_reqs,
.main_clk = "mcspi1_fck",
.prcm = {
.omap2 = {
@@ -1568,8 +1404,6 @@ static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
static struct omap_hwmod omap34xx_mcspi2 = {
.name = "mcspi2",
- .mpu_irqs = omap2_mcspi2_mpu_irqs,
- .sdma_reqs = omap2_mcspi2_sdma_reqs,
.main_clk = "mcspi2_fck",
.prcm = {
.omap2 = {
@@ -1585,18 +1419,7 @@ static struct omap_hwmod omap34xx_mcspi2 = {
};
/* mcspi3 */
-static struct omap_hwmod_irq_info omap34xx_mcspi3_mpu_irqs[] = {
- { .name = "irq", .irq = 91 + OMAP_INTC_START, }, /* 91 */
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap34xx_mcspi3_sdma_reqs[] = {
- { .name = "tx0", .dma_req = 15 },
- { .name = "rx0", .dma_req = 16 },
- { .name = "tx1", .dma_req = 23 },
- { .name = "rx1", .dma_req = 24 },
- { .dma_req = -1 }
-};
static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
.num_chipselect = 2,
@@ -1604,8 +1427,6 @@ static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
static struct omap_hwmod omap34xx_mcspi3 = {
.name = "mcspi3",
- .mpu_irqs = omap34xx_mcspi3_mpu_irqs,
- .sdma_reqs = omap34xx_mcspi3_sdma_reqs,
.main_clk = "mcspi3_fck",
.prcm = {
.omap2 = {
@@ -1621,16 +1442,7 @@ static struct omap_hwmod omap34xx_mcspi3 = {
};
/* mcspi4 */
-static struct omap_hwmod_irq_info omap34xx_mcspi4_mpu_irqs[] = {
- { .name = "irq", .irq = 48 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap34xx_mcspi4_sdma_reqs[] = {
- { .name = "tx0", .dma_req = 70 }, /* DMA_SPI4_TX0 */
- { .name = "rx0", .dma_req = 71 }, /* DMA_SPI4_RX0 */
- { .dma_req = -1 }
-};
static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = {
.num_chipselect = 1,
@@ -1638,8 +1450,6 @@ static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = {
static struct omap_hwmod omap34xx_mcspi4 = {
.name = "mcspi4",
- .mpu_irqs = omap34xx_mcspi4_mpu_irqs,
- .sdma_reqs = omap34xx_mcspi4_sdma_reqs,
.main_clk = "mcspi4_fck",
.prcm = {
.omap2 = {
@@ -1673,16 +1483,9 @@ static struct omap_hwmod_class usbotg_class = {
};
/* usb_otg_hs */
-static struct omap_hwmod_irq_info omap3xxx_usbhsotg_mpu_irqs[] = {
-
- { .name = "mc", .irq = 92 + OMAP_INTC_START, },
- { .name = "dma", .irq = 93 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
.name = "usb_otg_hs",
- .mpu_irqs = omap3xxx_usbhsotg_mpu_irqs,
.main_clk = "hsotgusb_ick",
.prcm = {
.omap2 = {
@@ -1691,7 +1494,7 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
.module_offs = CORE_MOD,
.idlest_reg_id = 1,
.idlest_idle_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT,
- .idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT
+ .idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT,
},
},
.class = &usbotg_class,
@@ -1711,10 +1514,6 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
};
/* usb_otg_hs */
-static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = {
- { .name = "mc", .irq = 71 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod_class am35xx_usbotg_class = {
.name = "am35xx_usbotg",
@@ -1722,7 +1521,6 @@ static struct omap_hwmod_class am35xx_usbotg_class = {
static struct omap_hwmod am35xx_usbhsotg_hwmod = {
.name = "am35x_otg_hs",
- .mpu_irqs = am35xx_usbhsotg_mpu_irqs,
.main_clk = "hsotgusb_fck",
.class = &am35xx_usbotg_class,
.flags = HWMOD_NO_IDLEST,
@@ -1747,16 +1545,7 @@ static struct omap_hwmod_class omap34xx_mmc_class = {
/* MMC/SD/SDIO1 */
-static struct omap_hwmod_irq_info omap34xx_mmc1_mpu_irqs[] = {
- { .irq = 83 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap34xx_mmc1_sdma_reqs[] = {
- { .name = "tx", .dma_req = 61, },
- { .name = "rx", .dma_req = 62, },
- { .dma_req = -1 }
-};
static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = {
{ .role = "dbck", .clk = "omap_32k_fck", },
@@ -1774,8 +1563,6 @@ static struct omap_hsmmc_dev_attr mmc1_pre_es3_dev_attr = {
static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = {
.name = "mmc1",
- .mpu_irqs = omap34xx_mmc1_mpu_irqs,
- .sdma_reqs = omap34xx_mmc1_sdma_reqs,
.opt_clks = omap34xx_mmc1_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks),
.main_clk = "mmchs1_fck",
@@ -1794,8 +1581,6 @@ static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = {
static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = {
.name = "mmc1",
- .mpu_irqs = omap34xx_mmc1_mpu_irqs,
- .sdma_reqs = omap34xx_mmc1_sdma_reqs,
.opt_clks = omap34xx_mmc1_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks),
.main_clk = "mmchs1_fck",
@@ -1814,16 +1599,7 @@ static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = {
/* MMC/SD/SDIO2 */
-static struct omap_hwmod_irq_info omap34xx_mmc2_mpu_irqs[] = {
- { .irq = 86 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap34xx_mmc2_sdma_reqs[] = {
- { .name = "tx", .dma_req = 47, },
- { .name = "rx", .dma_req = 48, },
- { .dma_req = -1 }
-};
static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = {
{ .role = "dbck", .clk = "omap_32k_fck", },
@@ -1836,8 +1612,6 @@ static struct omap_hsmmc_dev_attr mmc2_pre_es3_dev_attr = {
static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = {
.name = "mmc2",
- .mpu_irqs = omap34xx_mmc2_mpu_irqs,
- .sdma_reqs = omap34xx_mmc2_sdma_reqs,
.opt_clks = omap34xx_mmc2_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks),
.main_clk = "mmchs2_fck",
@@ -1856,8 +1630,6 @@ static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = {
static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = {
.name = "mmc2",
- .mpu_irqs = omap34xx_mmc2_mpu_irqs,
- .sdma_reqs = omap34xx_mmc2_sdma_reqs,
.opt_clks = omap34xx_mmc2_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks),
.main_clk = "mmchs2_fck",
@@ -1875,16 +1647,7 @@ static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = {
/* MMC/SD/SDIO3 */
-static struct omap_hwmod_irq_info omap34xx_mmc3_mpu_irqs[] = {
- { .irq = 94 + OMAP_INTC_START, },
- { .irq = -1 },
-};
-static struct omap_hwmod_dma_info omap34xx_mmc3_sdma_reqs[] = {
- { .name = "tx", .dma_req = 77, },
- { .name = "rx", .dma_req = 78, },
- { .dma_req = -1 }
-};
static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = {
{ .role = "dbck", .clk = "omap_32k_fck", },
@@ -1892,8 +1655,6 @@ static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = {
static struct omap_hwmod omap3xxx_mmc3_hwmod = {
.name = "mmc3",
- .mpu_irqs = omap34xx_mmc3_mpu_irqs,
- .sdma_reqs = omap34xx_mmc3_sdma_reqs,
.opt_clks = omap34xx_mmc3_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc3_opt_clks),
.main_clk = "mmchs3_fck",
@@ -1931,17 +1692,11 @@ static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
.sysc = &omap3xxx_usb_host_hs_sysc,
};
-static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
- { .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
- { .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
.name = "usb_host_hs",
.class = &omap3xxx_usb_host_hs_hwmod_class,
.clkdm_name = "usbhost_clkdm",
- .mpu_irqs = omap3xxx_usb_host_hs_irqs,
.main_clk = "usbhost_48m_fck",
.prcm = {
.omap2 = {
@@ -2015,16 +1770,11 @@ static struct omap_hwmod_class omap3xxx_usb_tll_hs_hwmod_class = {
.sysc = &omap3xxx_usb_tll_hs_sysc,
};
-static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = {
- { .name = "tll-irq", .irq = 78 + OMAP_INTC_START, },
- { .irq = -1 },
-};
static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
.name = "usb_tll_hs",
.class = &omap3xxx_usb_tll_hs_hwmod_class,
.clkdm_name = "core_l4_clkdm",
- .mpu_irqs = omap3xxx_usb_tll_hs_irqs,
.main_clk = "usbtll_fck",
.prcm = {
.omap2 = {
@@ -2039,7 +1789,6 @@ static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
static struct omap_hwmod omap3xxx_hdq1w_hwmod = {
.name = "hdq1w",
- .mpu_irqs = omap2_hdq1w_mpu_irqs,
.main_clk = "hdq_fck",
.prcm = {
.omap2 = {
@@ -2134,16 +1883,10 @@ static struct omap_hwmod_class omap3xxx_gpmc_hwmod_class = {
.sysc = &omap3xxx_gpmc_sysc,
};
-static struct omap_hwmod_irq_info omap3xxx_gpmc_irqs[] = {
- { .irq = 20 + OMAP_INTC_START, },
- { .irq = -1 }
-};
-
static struct omap_hwmod omap3xxx_gpmc_hwmod = {
.name = "gpmc",
.class = &omap3xxx_gpmc_hwmod_class,
.clkdm_name = "core_l3_clkdm",
- .mpu_irqs = omap3xxx_gpmc_irqs,
.main_clk = "gpmc_fck",
/* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
.flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
@@ -2167,37 +1910,19 @@ static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_l3_main_addrs[] = {
- {
- .pa_start = 0x68000000,
- .pa_end = 0x6800ffff,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
/* MPU -> L3 interface */
static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
.master = &omap3xxx_mpu_hwmod,
.slave = &omap3xxx_l3_main_hwmod,
- .addr = omap3xxx_l3_main_addrs,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space omap3xxx_l4_emu_addrs[] = {
- {
- .pa_start = 0x54000000,
- .pa_end = 0x547fffff,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
/* l3 -> debugss */
static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_debugss = {
.master = &omap3xxx_l3_main_hwmod,
.slave = &omap3xxx_debugss_hwmod,
- .addr = omap3xxx_l4_emu_addrs,
.user = OCP_USER_MPU,
};
@@ -2215,7 +1940,7 @@ static struct omap_hwmod_ocp_if omap3xxx_dss__l3 = {
.omap2 = {
.l3_perm_bit = OMAP3_L3_CORE_FW_INIT_ID_DSS,
.flags = OMAP_FIREWALL_L3,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2256,18 +1981,16 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__pre_es3_mmc1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_pre_es3_mmc1_hwmod,
.clk = "mmchs1_ick",
- .addr = omap2430_mmc1_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
- .flags = OMAP_FIREWALL_L4
+ .flags = OMAP_FIREWALL_L4,
};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__es3plus_mmc1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_es3plus_mmc1_hwmod,
.clk = "mmchs1_ick",
- .addr = omap2430_mmc1_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
- .flags = OMAP_FIREWALL_L4
+ .flags = OMAP_FIREWALL_L4,
};
/* L4 CORE -> MMC2 interface */
@@ -2275,126 +1998,70 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__pre_es3_mmc2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_pre_es3_mmc2_hwmod,
.clk = "mmchs2_ick",
- .addr = omap2430_mmc2_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
- .flags = OMAP_FIREWALL_L4
+ .flags = OMAP_FIREWALL_L4,
};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__es3plus_mmc2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_es3plus_mmc2_hwmod,
.clk = "mmchs2_ick",
- .addr = omap2430_mmc2_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
- .flags = OMAP_FIREWALL_L4
+ .flags = OMAP_FIREWALL_L4,
};
/* L4 CORE -> MMC3 interface */
-static struct omap_hwmod_addr_space omap3xxx_mmc3_addr_space[] = {
- {
- .pa_start = 0x480ad000,
- .pa_end = 0x480ad1ff,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc3 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_mmc3_hwmod,
.clk = "mmchs3_ick",
- .addr = omap3xxx_mmc3_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
- .flags = OMAP_FIREWALL_L4
+ .flags = OMAP_FIREWALL_L4,
};
/* L4 CORE -> UART1 interface */
-static struct omap_hwmod_addr_space omap3xxx_uart1_addr_space[] = {
- {
- .pa_start = OMAP3_UART1_BASE,
- .pa_end = OMAP3_UART1_BASE + SZ_8K - 1,
- .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3_l4_core__uart1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_uart1_hwmod,
.clk = "uart1_ick",
- .addr = omap3xxx_uart1_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* L4 CORE -> UART2 interface */
-static struct omap_hwmod_addr_space omap3xxx_uart2_addr_space[] = {
- {
- .pa_start = OMAP3_UART2_BASE,
- .pa_end = OMAP3_UART2_BASE + SZ_1K - 1,
- .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3_l4_core__uart2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_uart2_hwmod,
.clk = "uart2_ick",
- .addr = omap3xxx_uart2_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* L4 PER -> UART3 interface */
-static struct omap_hwmod_addr_space omap3xxx_uart3_addr_space[] = {
- {
- .pa_start = OMAP3_UART3_BASE,
- .pa_end = OMAP3_UART3_BASE + SZ_1K - 1,
- .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3_l4_per__uart3 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_uart3_hwmod,
.clk = "uart3_ick",
- .addr = omap3xxx_uart3_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* L4 PER -> UART4 interface */
-static struct omap_hwmod_addr_space omap36xx_uart4_addr_space[] = {
- {
- .pa_start = OMAP3_UART4_BASE,
- .pa_end = OMAP3_UART4_BASE + SZ_1K - 1,
- .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap36xx_l4_per__uart4 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap36xx_uart4_hwmod,
.clk = "uart4_ick",
- .addr = omap36xx_uart4_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* AM35xx: L4 CORE -> UART4 interface */
-static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = {
- {
- .pa_start = OMAP3_UART4_AM35XX_BASE,
- .pa_end = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1,
- .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_uart4_hwmod,
.clk = "uart4_ick",
- .addr = am35xx_uart4_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2403,13 +2070,12 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_i2c1_hwmod,
.clk = "i2c1_ick",
- .addr = omap2_i2c1_addr_space,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_I2C1_REGION,
.l4_prot_group = 7,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2419,57 +2085,38 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_i2c2_hwmod,
.clk = "i2c2_ick",
- .addr = omap2_i2c2_addr_space,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_I2C2_REGION,
.l4_prot_group = 7,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* L4 CORE -> I2C3 interface */
-static struct omap_hwmod_addr_space omap3xxx_i2c3_addr_space[] = {
- {
- .pa_start = 0x48060000,
- .pa_end = 0x48060000 + SZ_128 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_i2c3_hwmod,
.clk = "i2c3_ick",
- .addr = omap3xxx_i2c3_addr_space,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_I2C3_REGION,
.l4_prot_group = 7,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* L4 CORE -> SR1 interface */
-static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
- {
- .pa_start = OMAP34XX_SR1_BASE,
- .pa_end = OMAP34XX_SR1_BASE + SZ_1K - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap34xx_l4_core__sr1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap34xx_sr1_hwmod,
.clk = "sr_l4_ick",
- .addr = omap3_sr1_addr_space,
.user = OCP_USER_MPU,
};
@@ -2477,25 +2124,15 @@ static struct omap_hwmod_ocp_if omap36xx_l4_core__sr1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap36xx_sr1_hwmod,
.clk = "sr_l4_ick",
- .addr = omap3_sr1_addr_space,
.user = OCP_USER_MPU,
};
/* L4 CORE -> SR1 interface */
-static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = {
- {
- .pa_start = OMAP34XX_SR2_BASE,
- .pa_end = OMAP34XX_SR2_BASE + SZ_1K - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap34xx_l4_core__sr2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap34xx_sr2_hwmod,
.clk = "sr_l4_ick",
- .addr = omap3_sr2_addr_space,
.user = OCP_USER_MPU,
};
@@ -2503,43 +2140,24 @@ static struct omap_hwmod_ocp_if omap36xx_l4_core__sr2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap36xx_sr2_hwmod,
.clk = "sr_l4_ick",
- .addr = omap3_sr2_addr_space,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space omap3xxx_usbhsotg_addrs[] = {
- {
- .pa_start = OMAP34XX_HSUSB_OTG_BASE,
- .pa_end = OMAP34XX_HSUSB_OTG_BASE + SZ_4K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_core -> usbhsotg */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__usbhsotg = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_usbhsotg_hwmod,
.clk = "l4_ick",
- .addr = omap3xxx_usbhsotg_addrs,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = {
- {
- .pa_start = AM35XX_IPSS_USBOTGSS_BASE,
- .pa_end = AM35XX_IPSS_USBOTGSS_BASE + SZ_4K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_core -> usbhsotg */
static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_usbhsotg_hwmod,
.clk = "hsotgusb_ick",
- .addr = am35xx_usbhsotg_addrs,
.user = OCP_USER_MPU,
};
@@ -2558,165 +2176,84 @@ static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer1_addrs[] = {
- {
- .pa_start = 0x48318000,
- .pa_end = 0x48318000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_wkup -> timer1 */
static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__timer1 = {
.master = &omap3xxx_l4_wkup_hwmod,
.slave = &omap3xxx_timer1_hwmod,
.clk = "gpt1_ick",
- .addr = omap3xxx_timer1_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer2_addrs[] = {
- {
- .pa_start = 0x49032000,
- .pa_end = 0x49032000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer2 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer2 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer2_hwmod,
.clk = "gpt2_ick",
- .addr = omap3xxx_timer2_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer3_addrs[] = {
- {
- .pa_start = 0x49034000,
- .pa_end = 0x49034000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer3 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer3 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer3_hwmod,
.clk = "gpt3_ick",
- .addr = omap3xxx_timer3_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer4_addrs[] = {
- {
- .pa_start = 0x49036000,
- .pa_end = 0x49036000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer4 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer4 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer4_hwmod,
.clk = "gpt4_ick",
- .addr = omap3xxx_timer4_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer5_addrs[] = {
- {
- .pa_start = 0x49038000,
- .pa_end = 0x49038000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer5 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer5 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer5_hwmod,
.clk = "gpt5_ick",
- .addr = omap3xxx_timer5_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer6_addrs[] = {
- {
- .pa_start = 0x4903A000,
- .pa_end = 0x4903A000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer6 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer6 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer6_hwmod,
.clk = "gpt6_ick",
- .addr = omap3xxx_timer6_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer7_addrs[] = {
- {
- .pa_start = 0x4903C000,
- .pa_end = 0x4903C000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer7 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer7 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer7_hwmod,
.clk = "gpt7_ick",
- .addr = omap3xxx_timer7_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer8_addrs[] = {
- {
- .pa_start = 0x4903E000,
- .pa_end = 0x4903E000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer8 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer8 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer8_hwmod,
.clk = "gpt8_ick",
- .addr = omap3xxx_timer8_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer9_addrs[] = {
- {
- .pa_start = 0x49040000,
- .pa_end = 0x49040000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> timer9 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer9 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_timer9_hwmod,
.clk = "gpt9_ick",
- .addr = omap3xxx_timer9_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2725,7 +2262,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer10 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_timer10_hwmod,
.clk = "gpt10_ick",
- .addr = omap2_timer10_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2734,43 +2270,24 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer11 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_timer11_hwmod,
.clk = "gpt11_ick",
- .addr = omap2_timer11_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_timer12_addrs[] = {
- {
- .pa_start = 0x48304000,
- .pa_end = 0x48304000 + SZ_1K - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_core -> timer12 */
static struct omap_hwmod_ocp_if omap3xxx_l4_sec__timer12 = {
.master = &omap3xxx_l4_sec_hwmod,
.slave = &omap3xxx_timer12_hwmod,
.clk = "gpt12_ick",
- .addr = omap3xxx_timer12_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_wkup -> wd_timer2 */
-static struct omap_hwmod_addr_space omap3xxx_wd_timer2_addrs[] = {
- {
- .pa_start = 0x48314000,
- .pa_end = 0x4831407f,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = {
.master = &omap3xxx_l4_wkup_hwmod,
.slave = &omap3xxx_wd_timer2_hwmod,
.clk = "wdt2_ick",
- .addr = omap3xxx_wd_timer2_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2779,13 +2296,12 @@ static struct omap_hwmod_ocp_if omap3430es1_l4_core__dss = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3430es1_dss_core_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION,
.l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2794,13 +2310,12 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_dss_core_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_DSS_CORE_REGION,
.l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2810,38 +2325,27 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_dss_dispc_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_dispc_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_DSS_DISPC_REGION,
.l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
- {
- .pa_start = 0x4804FC00,
- .pa_end = 0x4804FFFF,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-
/* l4_core -> dss_dsi1 */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_dss_dsi1_hwmod,
.clk = "dss_ick",
- .addr = omap3xxx_dss_dsi1_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_DSS_DSI_REGION,
.l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2851,13 +2355,12 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_rfbi = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_dss_rfbi_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_rfbi_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_DSS_RFBI_REGION,
.l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP ,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -2867,66 +2370,38 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_dss_venc_hwmod,
.clk = "dss_ick",
- .addr = omap2_dss_venc_addrs,
.fw = {
.omap2 = {
.l4_fw_region = OMAP3_L4_CORE_FW_DSS_VENC_REGION,
.l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
.flags = OMAP_FIREWALL_L4,
- }
+ },
},
.flags = OCPIF_SWSUP_IDLE,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_wkup -> gpio1 */
-static struct omap_hwmod_addr_space omap3xxx_gpio1_addrs[] = {
- {
- .pa_start = 0x48310000,
- .pa_end = 0x483101ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__gpio1 = {
.master = &omap3xxx_l4_wkup_hwmod,
.slave = &omap3xxx_gpio1_hwmod,
- .addr = omap3xxx_gpio1_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_per -> gpio2 */
-static struct omap_hwmod_addr_space omap3xxx_gpio2_addrs[] = {
- {
- .pa_start = 0x49050000,
- .pa_end = 0x490501ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio2 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_gpio2_hwmod,
- .addr = omap3xxx_gpio2_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_per -> gpio3 */
-static struct omap_hwmod_addr_space omap3xxx_gpio3_addrs[] = {
- {
- .pa_start = 0x49052000,
- .pa_end = 0x490521ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_gpio3_hwmod,
- .addr = omap3xxx_gpio3_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3002,53 +2477,26 @@ static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
};
/* l4_per -> gpio4 */
-static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
- {
- .pa_start = 0x49054000,
- .pa_end = 0x490541ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio4 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_gpio4_hwmod,
- .addr = omap3xxx_gpio4_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_per -> gpio5 */
-static struct omap_hwmod_addr_space omap3xxx_gpio5_addrs[] = {
- {
- .pa_start = 0x49056000,
- .pa_end = 0x490561ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio5 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_gpio5_hwmod,
- .addr = omap3xxx_gpio5_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_per -> gpio6 */
-static struct omap_hwmod_addr_space omap3xxx_gpio6_addrs[] = {
- {
- .pa_start = 0x49058000,
- .pa_end = 0x490581ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_gpio6_hwmod,
- .addr = omap3xxx_gpio6_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3064,9 +2512,9 @@ static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
{
.pa_start = 0x48056000,
.pa_end = 0x48056fff,
- .flags = ADDR_TYPE_RT
+ .flags = ADDR_TYPE_RT,
},
- { }
+ { },
};
/* l4_cfg -> dma_system */
@@ -3078,136 +2526,66 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dma_system = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp1_addrs[] = {
- {
- .name = "mpu",
- .pa_start = 0x48074000,
- .pa_end = 0x480740ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_core -> mcbsp1 */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_mcbsp1_hwmod,
.clk = "mcbsp1_ick",
- .addr = omap3xxx_mcbsp1_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp2_addrs[] = {
- {
- .name = "mpu",
- .pa_start = 0x49022000,
- .pa_end = 0x490220ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> mcbsp2 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_mcbsp2_hwmod,
.clk = "mcbsp2_ick",
- .addr = omap3xxx_mcbsp2_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp3_addrs[] = {
- {
- .name = "mpu",
- .pa_start = 0x49024000,
- .pa_end = 0x490240ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> mcbsp3 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_mcbsp3_hwmod,
.clk = "mcbsp3_ick",
- .addr = omap3xxx_mcbsp3_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp4_addrs[] = {
- {
- .name = "mpu",
- .pa_start = 0x49026000,
- .pa_end = 0x490260ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> mcbsp4 */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp4 = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_mcbsp4_hwmod,
.clk = "mcbsp4_ick",
- .addr = omap3xxx_mcbsp4_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp5_addrs[] = {
- {
- .name = "mpu",
- .pa_start = 0x48096000,
- .pa_end = 0x480960ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_core -> mcbsp5 */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp5 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_mcbsp5_hwmod,
.clk = "mcbsp5_ick",
- .addr = omap3xxx_mcbsp5_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp2_sidetone_addrs[] = {
- {
- .name = "sidetone",
- .pa_start = 0x49028000,
- .pa_end = 0x490280ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> mcbsp2_sidetone */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2_sidetone = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_mcbsp2_sidetone_hwmod,
.clk = "mcbsp2_ick",
- .addr = omap3xxx_mcbsp2_sidetone_addrs,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space omap3xxx_mcbsp3_sidetone_addrs[] = {
- {
- .name = "sidetone",
- .pa_start = 0x4902A000,
- .pa_end = 0x4902A0ff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
/* l4_per -> mcbsp3_sidetone */
static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3_sidetone = {
.master = &omap3xxx_l4_per_hwmod,
.slave = &omap3xxx_mcbsp3_sidetone_hwmod,
.clk = "mcbsp3_ick",
- .addr = omap3xxx_mcbsp3_sidetone_addrs,
.user = OCP_USER_MPU,
};
@@ -3223,7 +2601,6 @@ static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi1 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap34xx_mcspi1,
.clk = "mcspi1_ick",
- .addr = omap2_mcspi1_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3232,7 +2609,6 @@ static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi2 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap34xx_mcspi2,
.clk = "mcspi2_ick",
- .addr = omap2_mcspi2_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3241,25 +2617,15 @@ static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi3 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap34xx_mcspi3,
.clk = "mcspi3_ick",
- .addr = omap2430_mcspi3_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4 core -> mcspi4 interface */
-static struct omap_hwmod_addr_space omap34xx_mcspi4_addr_space[] = {
- {
- .pa_start = 0x480ba000,
- .pa_end = 0x480ba0ff,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi4 = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap34xx_mcspi4,
.clk = "mcspi4_ick",
- .addr = omap34xx_mcspi4_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3270,49 +2636,19 @@ static struct omap_hwmod_ocp_if omap3xxx_usb_host_hs__l3_main_2 = {
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space omap3xxx_usb_host_hs_addrs[] = {
- {
- .name = "uhh",
- .pa_start = 0x48064000,
- .pa_end = 0x480643ff,
- .flags = ADDR_TYPE_RT
- },
- {
- .name = "ohci",
- .pa_start = 0x48064400,
- .pa_end = 0x480647ff,
- },
- {
- .name = "ehci",
- .pa_start = 0x48064800,
- .pa_end = 0x48064cff,
- },
- {}
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_host_hs = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_usb_host_hs_hwmod,
.clk = "usbhost_ick",
- .addr = omap3xxx_usb_host_hs_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
-static struct omap_hwmod_addr_space omap3xxx_usb_tll_hs_addrs[] = {
- {
- .name = "tll",
- .pa_start = 0x48062000,
- .pa_end = 0x48062fff,
- .flags = ADDR_TYPE_RT
- },
- {}
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_tll_hs = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_usb_tll_hs_hwmod,
.clk = "usbtll_ick",
- .addr = omap3xxx_usb_tll_hs_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3321,35 +2657,17 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__hdq1w = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_hdq1w_hwmod,
.clk = "hdq_ick",
- .addr = omap2_hdq1w_addr_space,
.user = OCP_USER_MPU | OCP_USER_SDMA,
.flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE,
};
/* l4_wkup -> 32ksync_counter */
-static struct omap_hwmod_addr_space omap3xxx_counter_32k_addrs[] = {
- {
- .pa_start = 0x48320000,
- .pa_end = 0x4832001f,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
-static struct omap_hwmod_addr_space omap3xxx_gpmc_addrs[] = {
- {
- .pa_start = 0x6e000000,
- .pa_end = 0x6e000fff,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = {
.master = &omap3xxx_l4_wkup_hwmod,
.slave = &omap3xxx_counter_32k_hwmod,
.clk = "omap_32ksync_ick",
- .addr = omap3xxx_counter_32k_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3434,7 +2752,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = {
.master = &omap3xxx_l3_main_hwmod,
.slave = &omap3xxx_gpmc_hwmod,
.clk = "core_l3_ick",
- .addr = omap3xxx_gpmc_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3459,20 +2776,10 @@ static struct omap_hwmod_class omap3xxx_sham_class = {
.sysc = &omap3_sham_sysc,
};
-static struct omap_hwmod_irq_info omap3_sham_mpu_irqs[] = {
- { .irq = 49 + OMAP_INTC_START, },
- { .irq = -1 }
-};
-static struct omap_hwmod_dma_info omap3_sham_sdma_reqs[] = {
- { .name = "rx", .dma_req = 69, },
- { .dma_req = -1 }
-};
static struct omap_hwmod omap3xxx_sham_hwmod = {
.name = "sham",
- .mpu_irqs = omap3_sham_mpu_irqs,
- .sdma_reqs = omap3_sham_sdma_reqs,
.main_clk = "sha12_ick",
.prcm = {
.omap2 = {
@@ -3486,20 +2793,11 @@ static struct omap_hwmod omap3xxx_sham_hwmod = {
.class = &omap3xxx_sham_class,
};
-static struct omap_hwmod_addr_space omap3xxx_sham_addrs[] = {
- {
- .pa_start = 0x480c3000,
- .pa_end = 0x480c3000 + 0x64 - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__sham = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_sham_hwmod,
.clk = "sha12_ick",
- .addr = omap3xxx_sham_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3525,15 +2823,9 @@ static struct omap_hwmod_class omap3xxx_aes_class = {
.sysc = &omap3_aes_sysc,
};
-static struct omap_hwmod_dma_info omap3_aes_sdma_reqs[] = {
- { .name = "tx", .dma_req = 65, },
- { .name = "rx", .dma_req = 66, },
- { .dma_req = -1 }
-};
static struct omap_hwmod omap3xxx_aes_hwmod = {
.name = "aes",
- .sdma_reqs = omap3_aes_sdma_reqs,
.main_clk = "aes2_ick",
.prcm = {
.omap2 = {
@@ -3547,20 +2839,11 @@ static struct omap_hwmod omap3xxx_aes_hwmod = {
.class = &omap3xxx_aes_class,
};
-static struct omap_hwmod_addr_space omap3xxx_aes_addrs[] = {
- {
- .pa_start = 0x480c5000,
- .pa_end = 0x480c5000 + 0x50 - 1,
- .flags = ADDR_TYPE_RT
- },
- { }
-};
static struct omap_hwmod_ocp_if omap3xxx_l4_core__aes = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_aes_hwmod,
.clk = "aes2_ick",
- .addr = omap3xxx_aes_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -3661,28 +2944,28 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
/* GP-only hwmod links */
static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_sec__timer12,
- NULL
+ NULL,
};
static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_sec__timer12,
- NULL
+ NULL,
};
static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_sec__timer12,
- NULL
+ NULL,
};
/* crypto hwmod links */
static struct omap_hwmod_ocp_if *omap34xx_sham_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__sham,
- NULL
+ NULL,
};
static struct omap_hwmod_ocp_if *omap34xx_aes_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__aes,
- NULL
+ NULL,
};
static struct omap_hwmod_ocp_if *omap36xx_sham_hwmod_ocp_ifs[] __initdata = {
@@ -3710,14 +2993,14 @@ static struct omap_hwmod_ocp_if *am35xx_sham_hwmod_ocp_ifs[] __initdata = {
static struct omap_hwmod_ocp_if *am35xx_aes_hwmod_ocp_ifs[] __initdata = {
/* &omap3xxx_l4_core__aes, */
- NULL
+ NULL,
};
/* 3430ES1-only hwmod links */
static struct omap_hwmod_ocp_if *omap3430es1_hwmod_ocp_ifs[] __initdata = {
&omap3430es1_dss__l3,
&omap3430es1_l4_core__dss,
- NULL
+ NULL,
};
/* 3430ES2+-only hwmod links */
@@ -3729,21 +3012,21 @@ static struct omap_hwmod_ocp_if *omap3430es2plus_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_usb_host_hs__l3_main_2,
&omap3xxx_l4_core__usb_host_hs,
&omap3xxx_l4_core__usb_tll_hs,
- NULL
+ NULL,
};
/* <= 3430ES3-only hwmod links */
static struct omap_hwmod_ocp_if *omap3430_pre_es3_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__pre_es3_mmc1,
&omap3xxx_l4_core__pre_es3_mmc2,
- NULL
+ NULL,
};
/* 3430ES3+-only hwmod links */
static struct omap_hwmod_ocp_if *omap3430_es3plus_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__es3plus_mmc1,
&omap3xxx_l4_core__es3plus_mmc2,
- NULL
+ NULL,
};
/* 34xx-only hwmod links (all ES revisions) */
@@ -3757,7 +3040,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__mmu_isp,
&omap3xxx_l3_main__mmu_iva,
&omap3xxx_l4_core__ssi,
- NULL
+ NULL,
};
/* 36xx-only hwmod links (all ES revisions) */
@@ -3781,7 +3064,7 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__mmu_isp,
&omap3xxx_l3_main__mmu_iva,
&omap3xxx_l4_core__ssi,
- NULL
+ NULL,
};
static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = {
@@ -3800,7 +3083,7 @@ static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = {
&am35xx_l4_core__mdio,
&am35xx_emac__l3,
&am35xx_l4_core__emac,
- NULL
+ NULL,
};
static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = {
@@ -3808,7 +3091,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__dss_dsi1,
&omap3xxx_l4_core__dss_rfbi,
&omap3xxx_l4_core__dss_venc,
- NULL
+ NULL,
};
/**
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index 61f2f301d739..afbce1f6f641 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -442,6 +442,31 @@ static struct omap_hwmod am43xx_adc_tsc_hwmod = {
},
};
+static struct omap_hwmod_class_sysconfig am43xx_des_sysc = {
+ .rev_offs = 0x30,
+ .sysc_offs = 0x34,
+ .syss_offs = 0x38,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class am43xx_des_hwmod_class = {
+ .name = "des",
+ .sysc = &am43xx_des_sysc,
+};
+
+static struct omap_hwmod am43xx_des_hwmod = {
+ .name = "des",
+ .class = &am43xx_des_hwmod_class,
+ .clkdm_name = "l3_clkdm",
+ .main_clk = "l3_gclk",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = AM43XX_CM_PER_DES_CLKCTRL_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
/* dss */
static struct omap_hwmod am43xx_dss_core_hwmod = {
@@ -870,6 +895,13 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+static struct omap_hwmod_ocp_if am43xx_l3_main__des = {
+ .master = &am33xx_l3_main_hwmod,
+ .slave = &am43xx_des_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU,
+};
+
static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l4_wkup__synctimer,
&am43xx_l4_ls__timer8,
@@ -917,6 +949,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l4_per__i2c2,
&am33xx_l4_per__i2c3,
&am33xx_l4_per__mailbox,
+ &am33xx_l4_per__rng,
&am33xx_l4_ls__mcasp0,
&am33xx_l4_ls__mcasp1,
&am33xx_l4_ls__mmc0,
@@ -950,6 +983,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_cpgmac0__mdio,
&am33xx_l3_main__sha0,
&am33xx_l3_main__aes0,
+ &am43xx_l3_main__des,
&am43xx_l4_ls__ocp2scp0,
&am43xx_l4_ls__ocp2scp1,
&am43xx_l3_s__usbotgss0,
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 1ab7096af8e2..d0585293a381 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -690,6 +690,78 @@ static struct omap_hwmod dra7xx_dss_hdmi_hwmod = {
.parent_hwmod = &dra7xx_dss_hwmod,
};
+/* AES (the 'P' (public) device) */
+static struct omap_hwmod_class_sysconfig dra7xx_aes_sysc = {
+ .rev_offs = 0x0080,
+ .sysc_offs = 0x0084,
+ .syss_offs = 0x0088,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class dra7xx_aes_hwmod_class = {
+ .name = "aes",
+ .sysc = &dra7xx_aes_sysc,
+ .rev = 2,
+};
+
+/* AES1 */
+static struct omap_hwmod dra7xx_aes1_hwmod = {
+ .name = "aes1",
+ .class = &dra7xx_aes_hwmod_class,
+ .clkdm_name = "l4sec_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4SEC_AES1_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4SEC_AES1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* AES2 */
+static struct omap_hwmod dra7xx_aes2_hwmod = {
+ .name = "aes2",
+ .class = &dra7xx_aes_hwmod_class,
+ .clkdm_name = "l4sec_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4SEC_AES2_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4SEC_AES2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* sha0 HIB2 (the 'P' (public) device) */
+static struct omap_hwmod_class_sysconfig dra7xx_sha0_sysc = {
+ .rev_offs = 0x100,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class dra7xx_sha0_hwmod_class = {
+ .name = "sham",
+ .sysc = &dra7xx_sha0_sysc,
+ .rev = 2,
+};
+
+struct omap_hwmod dra7xx_sha0_hwmod = {
+ .name = "sham",
+ .class = &dra7xx_sha0_hwmod_class,
+ .clkdm_name = "l4sec_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
/*
* 'elm' class
*
@@ -2541,6 +2613,62 @@ static struct omap_hwmod dra7xx_uart10_hwmod = {
},
};
+/* DES (the 'P' (public) device) */
+static struct omap_hwmod_class_sysconfig dra7xx_des_sysc = {
+ .rev_offs = 0x0030,
+ .sysc_offs = 0x0034,
+ .syss_offs = 0x0038,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class dra7xx_des_hwmod_class = {
+ .name = "des",
+ .sysc = &dra7xx_des_sysc,
+};
+
+/* DES */
+static struct omap_hwmod dra7xx_des_hwmod = {
+ .name = "des",
+ .class = &dra7xx_des_hwmod_class,
+ .clkdm_name = "l4sec_clkdm",
+ .main_clk = "l3_iclk_div",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
+/* rng */
+static struct omap_hwmod_class_sysconfig dra7xx_rng_sysc = {
+ .rev_offs = 0x1fe0,
+ .sysc_offs = 0x1fe4,
+ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dra7xx_rng_hwmod_class = {
+ .name = "rng",
+ .sysc = &dra7xx_rng_sysc,
+};
+
+static struct omap_hwmod dra7xx_rng_hwmod = {
+ .name = "rng",
+ .class = &dra7xx_rng_hwmod_class,
+ .flags = HWMOD_SWSUP_SIDLE,
+ .clkdm_name = "l4sec_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4SEC_RNG_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4SEC_RNG_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+};
+
/*
* 'usb_otg_ss' class
*
@@ -2929,6 +3057,30 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* l3_main_1 -> aes1 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__aes1 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_aes1_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> aes2 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__aes2 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_aes2_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> sha0 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__sha0 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_sha0_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l4_per2 -> mcasp1 */
static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp1 = {
.master = &dra7xx_l4_per2_hwmod,
@@ -3642,6 +3794,14 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart7 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* l4_per1 -> des */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__des = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_des_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l4_per2 -> uart8 */
static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart8 = {
.master = &dra7xx_l4_per2_hwmod,
@@ -3666,6 +3826,13 @@ static struct omap_hwmod_ocp_if dra7xx_l4_wkup__uart10 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* l4_per1 -> rng */
+static struct omap_hwmod_ocp_if dra7xx_l4_per1__rng = {
+ .master = &dra7xx_l4_per1_hwmod,
+ .slave = &dra7xx_rng_hwmod,
+ .user = OCP_USER_MPU,
+};
+
/* l4_per3 -> usb_otg_ss1 */
static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = {
.master = &dra7xx_l4_per3_hwmod,
@@ -3800,6 +3967,9 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l3_main_1__dss,
&dra7xx_l3_main_1__dispc,
&dra7xx_l3_main_1__hdmi,
+ &dra7xx_l3_main_1__aes1,
+ &dra7xx_l3_main_1__aes2,
+ &dra7xx_l3_main_1__sha0,
&dra7xx_l4_per1__elm,
&dra7xx_l4_wkup__gpio1,
&dra7xx_l4_per1__gpio2,
@@ -3845,7 +4015,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l3_main_1__pciess2,
&dra7xx_l4_cfg__pciess2,
&dra7xx_l3_main_1__qspi,
- &dra7xx_l4_per3__rtcss,
&dra7xx_l4_cfg__sata,
&dra7xx_l4_cfg__smartreflex_core,
&dra7xx_l4_cfg__smartreflex_mpu,
@@ -3875,6 +4044,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l4_per2__uart8,
&dra7xx_l4_per2__uart9,
&dra7xx_l4_wkup__uart10,
+ &dra7xx_l4_per1__des,
&dra7xx_l4_per3__usb_otg_ss1,
&dra7xx_l4_per3__usb_otg_ss2,
&dra7xx_l4_per3__usb_otg_ss3,
@@ -3892,6 +4062,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
/* GP-only hwmod links */
static struct omap_hwmod_ocp_if *dra7xx_gp_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l4_wkup__timer12,
+ &dra7xx_l4_per1__rng,
NULL,
};
@@ -3905,6 +4076,11 @@ static struct omap_hwmod_ocp_if *dra72x_hwmod_ocp_ifs[] __initdata = {
NULL,
};
+static struct omap_hwmod_ocp_if *dra74x_dra72x_hwmod_ocp_ifs[] __initdata = {
+ &dra7xx_l4_per3__rtcss,
+ NULL,
+};
+
int __init dra7xx_hwmod_init(void)
{
int ret;
@@ -3920,5 +4096,9 @@ int __init dra7xx_hwmod_init(void)
if (!ret && omap_type() == OMAP2_DEVICE_TYPE_GP)
ret = omap_hwmod_register_links(dra7xx_gp_hwmod_ocp_ifs);
+ /* now for the IPs *NOT* in dra71 */
+ if (!ret && !of_machine_is_compatible("ti,dra718"))
+ ret = omap_hwmod_register_links(dra74x_dra72x_hwmod_ocp_ifs);
+
return ret;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index 11ed5a17dd77..cdfbb44ceb0c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -19,22 +19,7 @@
#include "display.h"
/* Common address space across OMAP2xxx/3xxx */
-extern struct omap_hwmod_addr_space omap2_i2c1_addr_space[];
-extern struct omap_hwmod_addr_space omap2_i2c2_addr_space[];
-extern struct omap_hwmod_addr_space omap2_dss_addrs[];
-extern struct omap_hwmod_addr_space omap2_dss_dispc_addrs[];
-extern struct omap_hwmod_addr_space omap2_dss_rfbi_addrs[];
-extern struct omap_hwmod_addr_space omap2_dss_venc_addrs[];
-extern struct omap_hwmod_addr_space omap2_timer10_addrs[];
-extern struct omap_hwmod_addr_space omap2_timer11_addrs[];
-extern struct omap_hwmod_addr_space omap2430_mmc1_addr_space[];
-extern struct omap_hwmod_addr_space omap2430_mmc2_addr_space[];
-extern struct omap_hwmod_addr_space omap2_mcspi1_addr_space[];
-extern struct omap_hwmod_addr_space omap2_mcspi2_addr_space[];
-extern struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[];
extern struct omap_hwmod_addr_space omap2_dma_system_addrs[];
-extern struct omap_hwmod_addr_space omap2_mcbsp1_addrs[];
-extern struct omap_hwmod_addr_space omap2_hdq1w_addr_space[];
/* Common IP block data across OMAP2xxx */
extern struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr;
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 05e20aaf68dd..477910a48448 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -31,7 +31,6 @@
#include "common.h"
#include "common-board-devices.h"
-#include "dss-common.h"
#include "control.h"
#include "omap_device.h"
#include "omap-pm.h"
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 0b339861d751..003a6cb248be 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -114,8 +114,7 @@ static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1,
pwrdm->ret_mem_off_counter[i]);
- seq_printf(s, "\n");
-
+ seq_putc(s, '\n');
return 0;
}
@@ -138,7 +137,7 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
pwrdm->state_timer[i]);
- seq_printf(s, "\n");
+ seq_putc(s, '\n');
return 0;
}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 678d2a31dcb8..76b0454ddc49 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -30,7 +30,6 @@
#include "powerdomain.h"
#include "clockdomain.h"
#include "pm.h"
-#include "twl-common.h"
#ifdef CONFIG_SUSPEND
/*
@@ -72,42 +71,6 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
}
#endif
-static int __init _init_omap_device(char *name)
-{
- struct omap_hwmod *oh;
- struct platform_device *pdev;
-
- oh = omap_hwmod_lookup(name);
- if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
- __func__, name))
- return -ENODEV;
-
- pdev = omap_device_build(oh->name, 0, oh, NULL, 0);
- if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n",
- __func__, name))
- return -ENODEV;
-
- return 0;
-}
-
-/*
- * Build omap_devices for processors and bus.
- */
-static void __init omap2_init_processor_devices(void)
-{
- _init_omap_device("mpu");
- if (omap3_has_iva())
- _init_omap_device("iva");
-
- if (cpu_is_omap44xx()) {
- _init_omap_device("l3_main_1");
- _init_omap_device("dsp");
- _init_omap_device("iva");
- } else {
- _init_omap_device("l3_main");
- }
-}
-
int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
{
clkdm_allow_idle(clkdm);
@@ -215,7 +178,7 @@ static int omap_pm_enter(suspend_state_t suspend_state)
static int omap_pm_begin(suspend_state_t state)
{
cpu_idle_poll_ctrl(true);
- if (cpu_is_omap34xx())
+ if (soc_is_omap34xx())
omap_prcm_irq_prepare();
return 0;
}
@@ -227,7 +190,7 @@ static void omap_pm_end(void)
static void omap_pm_finish(void)
{
- if (cpu_is_omap34xx())
+ if (soc_is_omap34xx())
omap_prcm_irq_complete();
}
@@ -252,7 +215,7 @@ void omap_common_suspend_init(void *pm_suspend)
static void __init omap3_init_voltages(void)
{
- if (!cpu_is_omap34xx())
+ if (!soc_is_omap34xx())
return;
omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu");
@@ -261,7 +224,7 @@ static void __init omap3_init_voltages(void)
static void __init omap4_init_voltages(void)
{
- if (!cpu_is_omap44xx())
+ if (!soc_is_omap44xx())
return;
omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu");
@@ -269,18 +232,8 @@ static void __init omap4_init_voltages(void)
omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
}
-static inline void omap_init_cpufreq(void)
-{
- struct platform_device_info devinfo = { .name = "omap-cpufreq" };
-
- if (!of_have_populated_dt())
- platform_device_register_full(&devinfo);
-}
-
static int __init omap2_common_pm_init(void)
{
- if (!of_have_populated_dt())
- omap2_init_processor_devices();
omap_pm_if_init();
return 0;
@@ -289,13 +242,9 @@ omap_postcore_initcall(omap2_common_pm_init);
int __init omap2_common_pm_late_init(void)
{
- if (of_have_populated_dt()) {
- omap3_twl_init();
- omap4_twl_init();
- }
-
/* Init the voltage layer */
- omap_pmic_late_init();
+ omap3_twl_init();
+ omap4_twl_init();
omap_voltage_late_init();
/* Initialize the voltages */
@@ -305,8 +254,5 @@ int __init omap2_common_pm_late_init(void)
/* Smartreflex device init */
omap_devinit_smartreflex();
- /* cpufreq dummy device instantiation */
- omap_init_cpufreq();
-
return 0;
}
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 178e22c146b7..b3870220612e 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -287,7 +287,7 @@ int __init omap4_pm_init(void)
/* Overwrite the default cpu_do_idle() */
arm_pm_idle = omap_default_idle;
- if (cpu_is_omap44xx())
+ if (cpu_is_omap44xx() || soc_is_omap54xx())
omap4_idle_init();
err2:
diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h
index babb5db5a3a4..e2ad14e77064 100644
--- a/arch/arm/mach-omap2/prcm43xx.h
+++ b/arch/arm/mach-omap2/prcm43xx.h
@@ -92,6 +92,7 @@
#define AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x04b8
#define AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x04c0
#define AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x04c8
+#define AM43XX_CM_PER_RNG_CLKCTRL_OFFSET 0x04e0
#define AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x0500
#define AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0508
#define AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x0528
@@ -133,6 +134,7 @@
#define AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x0050
#define AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x0058
#define AM43XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0028
+#define AM43XX_CM_PER_DES_CLKCTRL_OFFSET 0x0030
#define AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET 0x0560
#define AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET 0x0568
#define AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET 0x0570
diff --git a/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h b/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h
deleted file mode 100644
index 1ee58c281a31..000000000000
--- a/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SDRC register values for the Hynix H8MBX00U0MER-0EM
- *
- * Copyright (C) 2009 Texas Instruments, 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_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM
-#define __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM
-
-#include "sdrc.h"
-
-/* Hynix H8MBX00U0MER-0EM */
-static struct omap_sdrc_params h8mbx00u0mer0em_sdrc_params[] = {
- [0] = {
- .rate = 200000000,
- .actim_ctrla = 0xa2e1b4c6,
- .actim_ctrlb = 0x0002131c,
- .rfr_ctrl = 0x0005e601,
- .mr = 0x00000032,
- },
- [1] = {
- .rate = 166000000,
- .actim_ctrla = 0x629db4c6,
- .actim_ctrlb = 0x00012214,
- .rfr_ctrl = 0x0004dc01,
- .mr = 0x00000032,
- },
- [2] = {
- .rate = 100000000,
- .actim_ctrla = 0x51912284,
- .actim_ctrlb = 0x0002120e,
- .rfr_ctrl = 0x0002d101,
- .mr = 0x00000022,
- },
- [3] = {
- .rate = 83000000,
- .actim_ctrla = 0x31512283,
- .actim_ctrlb = 0x0001220a,
- .rfr_ctrl = 0x00025501,
- .mr = 0x00000022,
- },
- [4] = {
- .rate = 0
- },
-};
-
-#endif
diff --git a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
deleted file mode 100644
index 85cccc004c06..000000000000
--- a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SDRC register values for the Micron MT46H32M32LF-6
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Paul Walmsley
- *
- * 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_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
-#define ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
-
-#include "sdrc.h"
-
-/* Micron MT46H32M32LF-6 */
-/* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
-static struct omap_sdrc_params mt46h32m32lf6_sdrc_params[] = {
- [0] = {
- .rate = 166000000,
- .actim_ctrla = 0x9a9db4c6,
- .actim_ctrlb = 0x00011217,
- .rfr_ctrl = 0x0004dc01,
- .mr = 0x00000032,
- },
- [1] = {
- .rate = 165941176,
- .actim_ctrla = 0x9a9db4c6,
- .actim_ctrlb = 0x00011217,
- .rfr_ctrl = 0x0004dc01,
- .mr = 0x00000032,
- },
- [2] = {
- .rate = 83000000,
- .actim_ctrla = 0x51512283,
- .actim_ctrlb = 0x0001120c,
- .rfr_ctrl = 0x00025501,
- .mr = 0x00000032,
- },
- [3] = {
- .rate = 82970588,
- .actim_ctrla = 0x51512283,
- .actim_ctrlb = 0x0001120c,
- .rfr_ctrl = 0x00025501,
- .mr = 0x00000032,
- },
- [4] = {
- .rate = 0
- },
-};
-
-#endif
diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c
deleted file mode 100644
index 0fa7ffa9b5ed..000000000000
--- a/arch/arm/mach-omap2/sdram-nokia.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * SDRC register values for Nokia boards
- *
- * Copyright (C) 2008, 2010-2011 Nokia Corporation
- *
- * Lauri Leukkunen <lauri.leukkunen@nokia.com>
- *
- * Original code by Juha Yrjola <juha.yrjola@solidboot.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include "common.h"
-#include "sdram-nokia.h"
-#include "sdrc.h"
-
-/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */
-struct sdram_timings {
- u32 casl;
- u32 tDAL;
- u32 tDPL;
- u32 tRRD;
- u32 tRCD;
- u32 tRP;
- u32 tRAS;
- u32 tRC;
- u32 tRFC;
- u32 tXSR;
-
- u32 tREF; /* in ns */
-
- u32 tXP;
- u32 tCKE;
- u32 tWTR;
-};
-
-static const struct sdram_timings nokia_97dot6mhz_timings[] = {
- {
- .casl = 3,
- .tDAL = 30725,
- .tDPL = 15362,
- .tRRD = 10241,
- .tRCD = 20483,
- .tRP = 15362,
- .tRAS = 40967,
- .tRC = 56330,
- .tRFC = 138266,
- .tXSR = 204839,
-
- .tREF = 7798,
-
- .tXP = 2,
- .tCKE = 4,
- .tWTR = 2,
- },
-};
-
-static const struct sdram_timings nokia_166mhz_timings[] = {
- {
- .casl = 3,
- .tDAL = 33000,
- .tDPL = 15000,
- .tRRD = 12000,
- .tRCD = 22500,
- .tRP = 18000,
- .tRAS = 42000,
- .tRC = 66000,
- .tRFC = 138000,
- .tXSR = 200000,
-
- .tREF = 7800,
-
- .tXP = 2,
- .tCKE = 2,
- .tWTR = 2
- },
-};
-
-static const struct sdram_timings nokia_195dot2mhz_timings[] = {
- {
- .casl = 3,
- .tDAL = 30725,
- .tDPL = 15362,
- .tRRD = 10241,
- .tRCD = 20483,
- .tRP = 15362,
- .tRAS = 40967,
- .tRC = 56330,
- .tRFC = 138266,
- .tXSR = 204839,
-
- .tREF = 7752,
-
- .tXP = 2,
- .tCKE = 4,
- .tWTR = 2,
- },
-};
-
-static const struct sdram_timings nokia_200mhz_timings[] = {
- {
- .casl = 3,
- .tDAL = 30000,
- .tDPL = 15000,
- .tRRD = 10000,
- .tRCD = 20000,
- .tRP = 15000,
- .tRAS = 40000,
- .tRC = 55000,
- .tRFC = 140000,
- .tXSR = 200000,
-
- .tREF = 7800,
-
- .tXP = 2,
- .tCKE = 4,
- .tWTR = 2
- },
-};
-
-static const struct {
- long rate;
- struct sdram_timings const *data;
-} nokia_timings[] = {
- { 83000000, nokia_166mhz_timings },
- { 97600000, nokia_97dot6mhz_timings },
- { 100000000, nokia_200mhz_timings },
- { 166000000, nokia_166mhz_timings },
- { 195200000, nokia_195dot2mhz_timings },
- { 200000000, nokia_200mhz_timings },
-};
-static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1];
-
-static unsigned long sdrc_get_fclk_period(long rate)
-{
- /* In picoseconds */
- return 1000000000 / rate;
-}
-
-static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate)
-{
- unsigned long tick_ps;
-
- /* Calculate in picosecs to yield more exact results */
- tick_ps = sdrc_get_fclk_period(rate);
-
- return (time_ps + tick_ps - 1) / tick_ps;
-}
-#undef DEBUG
-#ifdef DEBUG
-static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
- int ticks, long rate, const char *name)
-#else
-static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
- int ticks)
-#endif
-{
- int mask, nr_bits;
-
- nr_bits = end_bit - st_bit + 1;
- if (ticks >= 1 << nr_bits)
- return -1;
- mask = (1 << nr_bits) - 1;
- *regval &= ~(mask << st_bit);
- *regval |= ticks << st_bit;
-#ifdef DEBUG
- printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks,
- (unsigned int)sdrc_get_fclk_period(rate) * ticks /
- 1000);
-#endif
-
- return 0;
-}
-
-#ifdef DEBUG
-#define SDRC_SET_ONE(reg, st, end, field, rate) \
- if (set_sdrc_timing_regval((reg), (st), (end), \
- memory_timings->field, (rate), #field) < 0) \
- err = -1;
-#else
-#define SDRC_SET_ONE(reg, st, end, field, rate) \
- if (set_sdrc_timing_regval((reg), (st), (end), \
- memory_timings->field) < 0) \
- err = -1;
-#endif
-
-#ifdef DEBUG
-static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
- int time, long rate, const char *name)
-#else
-static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
- int time, long rate)
-#endif
-{
- int ticks, ret;
- ret = 0;
-
- if (time == 0)
- ticks = 0;
- else
- ticks = sdrc_ps_to_ticks(time, rate);
-
-#ifdef DEBUG
- ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks,
- rate, name);
-#else
- ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks);
-#endif
-
- return ret;
-}
-
-#ifdef DEBUG
-#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
- if (set_sdrc_timing_regval_ps((reg), (st), (end), \
- memory_timings->field, \
- (rate), #field) < 0) \
- err = -1;
-
-#else
-#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
- if (set_sdrc_timing_regval_ps((reg), (st), (end), \
- memory_timings->field, (rate)) < 0) \
- err = -1;
-#endif
-
-static int sdrc_timings(int id, long rate,
- const struct sdram_timings *memory_timings)
-{
- u32 ticks_per_ms;
- u32 rfr, l;
- u32 actim_ctrla = 0, actim_ctrlb = 0;
- u32 rfr_ctrl;
- int err = 0;
- long l3_rate = rate / 1000;
-
- SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate);
- SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate);
-
- SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate);
-
- SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate);
- SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate);
- SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate);
-
- ticks_per_ms = l3_rate;
- rfr = memory_timings[0].tREF * ticks_per_ms / 1000000;
- if (rfr > 65535 + 50)
- rfr = 65535;
- else
- rfr -= 50;
-
-#ifdef DEBUG
- printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr);
-#endif
-
- l = rfr << 8;
- rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */
-
- nokia_sdrc_params[id].rate = rate;
- nokia_sdrc_params[id].actim_ctrla = actim_ctrla;
- nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb;
- nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl;
- nokia_sdrc_params[id].mr = 0x32;
-
- nokia_sdrc_params[id + 1].rate = 0;
-
- return err;
-}
-
-struct omap_sdrc_params *nokia_get_sdram_timings(void)
-{
- int err = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) {
- err |= sdrc_timings(i, nokia_timings[i].rate,
- nokia_timings[i].data);
- if (err)
- pr_err("%s: error with rate %ld: %d\n", __func__,
- nokia_timings[i].rate, err);
- }
-
- return err ? NULL : nokia_sdrc_params;
-}
-
diff --git a/arch/arm/mach-omap2/sdram-nokia.h b/arch/arm/mach-omap2/sdram-nokia.h
deleted file mode 100644
index ee63da5f8df0..000000000000
--- a/arch/arm/mach-omap2/sdram-nokia.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * SDRC register values for Nokia boards
- *
- * Copyright (C) 2010 Nokia
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-struct omap_sdrc_params *nokia_get_sdram_timings(void);
-
diff --git a/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h b/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h
deleted file mode 100644
index 003f7bf4e2e3..000000000000
--- a/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SDRC register values for the Numonyx M65KXXXXAM
- *
- * Copyright (C) 2009 Integration Software and Electronic Engineering.
- *
- * 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_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM
-#define __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM
-
-#include "sdrc.h"
-
-/* Numonyx M65KXXXXAM */
-static struct omap_sdrc_params m65kxxxxam_sdrc_params[] = {
- [0] = {
- .rate = 200000000,
- .actim_ctrla = 0xe321d4c6,
- .actim_ctrlb = 0x00022328,
- .rfr_ctrl = 0x0005e601,
- .mr = 0x00000032,
- },
- [1] = {
- .rate = 166000000,
- .actim_ctrla = 0xba9dc485,
- .actim_ctrlb = 0x00022321,
- .rfr_ctrl = 0x0004dc01,
- .mr = 0x00000032,
- },
- [2] = {
- .rate = 133000000,
- .actim_ctrla = 0x9a19b485,
- .actim_ctrlb = 0x0002231b,
- .rfr_ctrl = 0x0003de01,
- .mr = 0x00000032,
- },
- [3] = {
- .rate = 83000000,
- .actim_ctrla = 0x594ca242,
- .actim_ctrlb = 0x00022310,
- .rfr_ctrl = 0x00025501,
- .mr = 0x00000032,
- },
- [4] = {
- .rate = 0
- },
-};
-
-#endif
diff --git a/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
deleted file mode 100644
index 8dc3de5ebb5b..000000000000
--- a/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SDRC register values for the Qimonda HYB18M512160AF-6
- *
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Paul Walmsley
- *
- * 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_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
-#define ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
-
-#include "sdrc.h"
-
-/* Qimonda HYB18M512160AF-6 */
-static struct omap_sdrc_params hyb18m512160af6_sdrc_params[] = {
- [0] = {
- .rate = 166000000,
- .actim_ctrla = 0x629db4c6,
- .actim_ctrlb = 0x00012214,
- .rfr_ctrl = 0x0004dc01,
- .mr = 0x00000032,
- },
- [1] = {
- .rate = 165941176,
- .actim_ctrla = 0x629db4c6,
- .actim_ctrlb = 0x00012214,
- .rfr_ctrl = 0x0004dc01,
- .mr = 0x00000032,
- },
- [2] = {
- .rate = 83000000,
- .actim_ctrla = 0x31512283,
- .actim_ctrlb = 0x0001220a,
- .rfr_ctrl = 0x00025501,
- .mr = 0x00000022,
- },
- [3] = {
- .rate = 82970588,
- .actim_ctrla = 0x31512283,
- .actim_ctrlb = 0x0001220a,
- .rfr_ctrl = 0x00025501,
- .mr = 0x00000022,
- },
- [4] = {
- .rate = 0
- },
-};
-
-#endif
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
deleted file mode 100644
index 8e072de89fed..000000000000
--- a/arch/arm/mach-omap2/serial.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * arch/arm/mach-omap2/serial.c
- *
- * OMAP2 serial support.
- *
- * Copyright (C) 2005-2008 Nokia Corporation
- * Author: Paul Mundt <paul.mundt@nokia.com>
- *
- * Major rework for PM support by Kevin Hilman
- *
- * Based off of arch/arm/mach-omap/omap1/serial.c
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-#include <linux/console.h>
-#include <linux/omap-dma.h>
-#include <linux/platform_data/serial-omap.h>
-
-#include "common.h"
-#include "omap_hwmod.h"
-#include "omap_device.h"
-#include "omap-pm.h"
-#include "soc.h"
-#include "prm2xxx_3xxx.h"
-#include "pm.h"
-#include "cm2xxx_3xxx.h"
-#include "prm-regbits-34xx.h"
-#include "control.h"
-#include "mux.h"
-#include "serial.h"
-
-/*
- * NOTE: By default the serial auto_suspend timeout is disabled as it causes
- * lost characters over the serial ports. This means that the UART clocks will
- * stay on until power/autosuspend_delay is set for the uart from sysfs.
- * This also causes that any deeper omap sleep states are blocked.
- */
-#define DEFAULT_AUTOSUSPEND_DELAY -1
-
-#define MAX_UART_HWMOD_NAME_LEN 16
-
-struct omap_uart_state {
- int num;
-
- struct list_head node;
- struct omap_hwmod *oh;
- struct omap_device_pad default_omap_uart_pads[2];
-};
-
-static LIST_HEAD(uart_list);
-static u8 num_uarts;
-static u8 console_uart_id = -1;
-static u8 uart_debug;
-
-#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */
-#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */
-#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */
-
-static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
- {
- .dma_enabled = false,
- .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
- .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
- .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
- .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
- },
-};
-
-#ifdef CONFIG_PM
-static void omap_uart_enable_wakeup(struct device *dev, bool enable)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_device *od = to_omap_device(pdev);
-
- if (!od)
- return;
-
- if (enable)
- omap_hwmod_enable_wakeup(od->hwmods[0]);
- else
- omap_hwmod_disable_wakeup(od->hwmods[0]);
-}
-
-#else
-static void omap_uart_enable_wakeup(struct device *dev, bool enable)
-{}
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_OMAP_MUX
-
-#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28
-static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN],
- tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata;
-
-static void __init
-omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata,
- struct omap_uart_state *uart)
-{
- uart->default_omap_uart_pads[0].name = rx_pad_name;
- uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX |
- OMAP_DEVICE_PAD_WAKEUP;
- uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT |
- OMAP_MUX_MODE0;
- uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0;
- uart->default_omap_uart_pads[1].name = tx_pad_name;
- uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT |
- OMAP_MUX_MODE0;
- bdata->pads = uart->default_omap_uart_pads;
- bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads);
-}
-
-static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
- struct omap_uart_state *uart)
-{
- struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL;
- struct omap_mux *rx_mux = NULL, *tx_mux = NULL;
- char *rx_fmt, *tx_fmt;
- int uart_nr = bdata->id + 1;
-
- if (bdata->id != 2) {
- rx_fmt = "uart%d_rx.uart%d_rx";
- tx_fmt = "uart%d_tx.uart%d_tx";
- } else {
- rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx";
- tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx";
- }
-
- snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt,
- uart_nr, uart_nr);
- snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt,
- uart_nr, uart_nr);
-
- if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 &&
- omap_mux_get_by_name
- (tx_pad_name, &tx_partition, &tx_mux) >= 0) {
- u16 tx_mode, rx_mode;
-
- tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset);
- rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset);
-
- /*
- * Check if uart is used in default tx/rx mode i.e. in mux mode0
- * if yes then configure rx pin for wake up capability
- */
- if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode))
- omap_serial_fill_uart_tx_rx_pads(bdata, uart);
- }
-}
-#else
-static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
- struct omap_uart_state *uart)
-{
-}
-#endif
-
-static char *cmdline_find_option(char *str)
-{
- extern char *saved_command_line;
-
- return strstr(saved_command_line, str);
-}
-
-static int __init omap_serial_early_init(void)
-{
- if (of_have_populated_dt())
- return -ENODEV;
-
- do {
- char oh_name[MAX_UART_HWMOD_NAME_LEN];
- struct omap_hwmod *oh;
- struct omap_uart_state *uart;
- char uart_name[MAX_UART_HWMOD_NAME_LEN];
-
- snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
- "uart%d", num_uarts + 1);
- oh = omap_hwmod_lookup(oh_name);
- if (!oh)
- break;
-
- uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
- if (WARN_ON(!uart))
- return -ENODEV;
-
- uart->oh = oh;
- uart->num = num_uarts++;
- list_add_tail(&uart->node, &uart_list);
- snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
- "%s%d", OMAP_SERIAL_NAME, uart->num);
-
- if (cmdline_find_option(uart_name)) {
- console_uart_id = uart->num;
-
- if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) {
- uart_debug = true;
- pr_info("%s used as console in debug mode: uart%d clocks will not be gated",
- uart_name, uart->num);
- }
- }
- } while (1);
-
- return 0;
-}
-omap_postcore_initcall(omap_serial_early_init);
-
-/**
- * omap_serial_init_port() - initialize single serial port
- * @bdata: port specific board data pointer
- * @info: platform specific data pointer
- *
- * This function initialies serial driver for given port only.
- * Platforms can call this function instead of omap_serial_init()
- * if they don't plan to use all available UARTs as serial ports.
- *
- * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
- * use only one of the two.
- */
-void __init omap_serial_init_port(struct omap_board_data *bdata,
- struct omap_uart_port_info *info)
-{
- struct omap_uart_state *uart;
- struct omap_hwmod *oh;
- struct platform_device *pdev;
- void *pdata = NULL;
- u32 pdata_size = 0;
- char *name;
- struct omap_uart_port_info omap_up;
-
- if (WARN_ON(!bdata))
- return;
- if (WARN_ON(bdata->id < 0))
- return;
- if (WARN_ON(bdata->id >= num_uarts))
- return;
-
- list_for_each_entry(uart, &uart_list, node)
- if (bdata->id == uart->num)
- break;
- if (!info)
- info = omap_serial_default_info;
-
- oh = uart->oh;
- name = OMAP_SERIAL_DRIVER_NAME;
-
- omap_up.dma_enabled = info->dma_enabled;
- omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
- omap_up.flags = UPF_BOOT_AUTOCONF;
- omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
- omap_up.enable_wakeup = omap_uart_enable_wakeup;
- omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
- omap_up.dma_rx_timeout = info->dma_rx_timeout;
- omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
- omap_up.autosuspend_timeout = info->autosuspend_timeout;
-
- pdata = &omap_up;
- pdata_size = sizeof(struct omap_uart_port_info);
-
- if (WARN_ON(!oh))
- return;
-
- pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size);
- if (IS_ERR(pdev)) {
- WARN(1, "Could not build omap_device for %s: %s.\n", name,
- oh->name);
- return;
- }
-
- oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
-
- if (console_uart_id == bdata->id) {
- omap_device_enable(pdev);
- pm_runtime_set_active(&pdev->dev);
- }
-
- oh->dev_attr = uart;
-
- if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
- && !uart_debug)
- device_init_wakeup(&pdev->dev, true);
-}
-
-/**
- * omap_serial_board_init() - initialize all supported serial ports
- * @info: platform specific data pointer
- *
- * Initializes all available UARTs as serial ports. Platforms
- * can call this function when they want to have default behaviour
- * for serial ports (e.g initialize them all as serial ports).
- */
-void __init omap_serial_board_init(struct omap_uart_port_info *info)
-{
- struct omap_uart_state *uart;
- struct omap_board_data bdata;
-
- list_for_each_entry(uart, &uart_list, node) {
- bdata.id = uart->num;
- bdata.flags = 0;
- bdata.pads = NULL;
- bdata.pads_cnt = 0;
-
- omap_serial_check_wakeup(&bdata, uart);
-
- if (!info)
- omap_serial_init_port(&bdata, NULL);
- else
- omap_serial_init_port(&bdata, &info[uart->num]);
- }
-}
-
-/**
- * omap_serial_init() - initialize all supported serial ports
- *
- * Initializes all available UARTs.
- * Platforms can call this function when they want to have default behaviour
- * for serial ports (e.g initialize them all as serial ports).
- */
-void __init omap_serial_init(void)
-{
- omap_serial_board_init(NULL);
-}
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
deleted file mode 100644
index a72738eab009..000000000000
--- a/arch/arm/mach-omap2/twl-common.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * twl-common.c
- *
- * Copyright (C) 2011 Texas Instruments, Inc..
- * Author: Peter Ujfalusi <peter.ujfalusi@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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c/twl.h>
-#include <linux/gpio.h>
-#include <linux/string.h>
-#include <linux/phy/phy.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-
-#include "soc.h"
-#include "twl-common.h"
-#include "pm.h"
-#include "voltage.h"
-#include "mux.h"
-
-static struct i2c_board_info __initdata pmic_i2c_board_info = {
- .addr = 0x48,
- .flags = I2C_CLIENT_WAKE,
-};
-
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-static int twl_set_voltage(void *data, int target_uV)
-{
- struct voltagedomain *voltdm = (struct voltagedomain *)data;
- return voltdm_scale(voltdm, target_uV);
-}
-
-static int twl_get_voltage(void *data)
-{
- struct voltagedomain *voltdm = (struct voltagedomain *)data;
- return voltdm_get_voltage(voltdm);
-}
-#endif
-
-void __init omap_pmic_init(int bus, u32 clkrate,
- const char *pmic_type, int pmic_irq,
- struct twl4030_platform_data *pmic_data)
-{
- omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
- strlcpy(pmic_i2c_board_info.type, pmic_type,
- sizeof(pmic_i2c_board_info.type));
- pmic_i2c_board_info.irq = pmic_irq;
- pmic_i2c_board_info.platform_data = pmic_data;
-
- omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
-}
-
-#ifdef CONFIG_ARCH_OMAP4
-void __init omap4_pmic_init(const char *pmic_type,
- struct twl4030_platform_data *pmic_data,
- struct i2c_board_info *devices, int nr_devices)
-{
- /* PMIC part*/
- unsigned int irq;
-
- omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
- omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
- irq = omap4_xlate_irq(7 + OMAP44XX_IRQ_GIC_START);
- omap_pmic_init(1, 400, pmic_type, irq, pmic_data);
-
- /* Register additional devices on i2c1 bus if needed */
- if (devices)
- i2c_register_board_info(1, devices, nr_devices);
-}
-#endif
-
-void __init omap_pmic_late_init(void)
-{
- /* Init the OMAP TWL parameters (if PMIC has been registerd) */
- if (!pmic_i2c_board_info.irq)
- return;
-
- omap3_twl_init();
- omap4_twl_init();
-}
-
-#if defined(CONFIG_ARCH_OMAP3)
-static struct twl4030_usb_data omap3_usb_pdata = {
- .usb_mode = T2_USB_MODE_ULPI,
-};
-
-static int omap3_batt_table[] = {
-/* 0 C */
-30800, 29500, 28300, 27100,
-26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
-17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
-11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
-8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
-5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
-4040, 3910, 3790, 3670, 3550
-};
-
-static struct twl4030_bci_platform_data omap3_bci_pdata = {
- .battery_tmp_tbl = omap3_batt_table,
- .tblsize = ARRAY_SIZE(omap3_batt_table),
-};
-
-static struct twl4030_madc_platform_data omap3_madc_pdata = {
- .irq_line = 1,
-};
-
-static struct twl4030_codec_data omap3_codec;
-
-static struct twl4030_audio_data omap3_audio_pdata = {
- .audio_mclk = 26000000,
- .codec = &omap3_codec,
-};
-
-static struct regulator_consumer_supply omap3_vdda_dac_supplies[] = {
- REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
-};
-
-static struct regulator_init_data omap3_vdac_idata = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap3_vdda_dac_supplies),
- .consumer_supplies = omap3_vdda_dac_supplies,
-};
-
-static struct regulator_consumer_supply omap3_vpll2_supplies[] = {
- REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
- REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
- REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
-};
-
-static struct regulator_init_data omap3_vpll2_idata = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap3_vpll2_supplies),
- .consumer_supplies = omap3_vpll2_supplies,
-};
-
-static struct regulator_consumer_supply omap3_vdd1_supply[] = {
- REGULATOR_SUPPLY("vcc", "cpu0"),
-};
-
-static struct regulator_consumer_supply omap3_vdd2_supply[] = {
- REGULATOR_SUPPLY("vcc", "l3_main.0"),
-};
-
-static struct regulator_init_data omap3_vdd1 = {
- .constraints = {
- .name = "vdd_mpu_iva",
- .min_uV = 600000,
- .max_uV = 1450000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap3_vdd1_supply),
- .consumer_supplies = omap3_vdd1_supply,
-};
-
-static struct regulator_init_data omap3_vdd2 = {
- .constraints = {
- .name = "vdd_core",
- .min_uV = 600000,
- .max_uV = 1450000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap3_vdd2_supply),
- .consumer_supplies = omap3_vdd2_supply,
-};
-
-static struct twl_regulator_driver_data omap3_vdd1_drvdata = {
- .get_voltage = twl_get_voltage,
- .set_voltage = twl_set_voltage,
-};
-
-static struct twl_regulator_driver_data omap3_vdd2_drvdata = {
- .get_voltage = twl_get_voltage,
- .set_voltage = twl_set_voltage,
-};
-
-void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
- u32 pdata_flags, u32 regulators_flags)
-{
- if (!pmic_data->vdd1) {
- omap3_vdd1.driver_data = &omap3_vdd1_drvdata;
- omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva");
- pmic_data->vdd1 = &omap3_vdd1;
- }
- if (!pmic_data->vdd2) {
- omap3_vdd2.driver_data = &omap3_vdd2_drvdata;
- omap3_vdd2_drvdata.data = voltdm_lookup("core");
- pmic_data->vdd2 = &omap3_vdd2;
- }
-
- /* Common platform data configurations */
- if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
- pmic_data->usb = &omap3_usb_pdata;
-
- if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci)
- pmic_data->bci = &omap3_bci_pdata;
-
- if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc)
- pmic_data->madc = &omap3_madc_pdata;
-
- if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio)
- pmic_data->audio = &omap3_audio_pdata;
-
- /* Common regulator configurations */
- if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac)
- pmic_data->vdac = &omap3_vdac_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2)
- pmic_data->vpll2 = &omap3_vpll2_idata;
-}
-#endif /* CONFIG_ARCH_OMAP3 */
-
-#if defined(CONFIG_ARCH_OMAP4)
-static struct twl4030_usb_data omap4_usb_pdata = {
-};
-
-static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
- REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
-};
-
-static struct regulator_init_data omap4_vdac_idata = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
- .consumer_supplies = omap4_vdda_hdmi_dac_supplies,
- .supply_regulator = "V2V1",
-};
-
-static struct regulator_init_data omap4_vaux2_idata = {
- .constraints = {
- .min_uV = 1200000,
- .max_uV = 2800000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_vaux3_idata = {
- .constraints = {
- .min_uV = 1000000,
- .max_uV = 3000000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_consumer_supply omap4_vmmc_supply[] = {
- REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
-};
-
-/* VMMC1 for MMC1 card */
-static struct regulator_init_data omap4_vmmc_idata = {
- .constraints = {
- .min_uV = 1200000,
- .max_uV = 3000000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_vmmc_supply),
- .consumer_supplies = omap4_vmmc_supply,
-};
-
-static struct regulator_init_data omap4_vpp_idata = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 2500000,
- .apply_uV = true,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_vana_idata = {
- .constraints = {
- .min_uV = 2100000,
- .max_uV = 2100000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_consumer_supply omap4_vcxio_supply[] = {
- REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
- REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
- REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
-};
-
-static struct regulator_init_data omap4_vcxio_idata = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- .always_on = true,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_vcxio_supply),
- .consumer_supplies = omap4_vcxio_supply,
- .supply_regulator = "V2V1",
-};
-
-static struct regulator_init_data omap4_vusb_idata = {
- .constraints = {
- .min_uV = 3300000,
- .max_uV = 3300000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_init_data omap4_clk32kg_idata = {
- .constraints = {
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- },
-};
-
-static struct regulator_consumer_supply omap4_vdd1_supply[] = {
- REGULATOR_SUPPLY("vcc", "cpu0"),
-};
-
-static struct regulator_consumer_supply omap4_vdd2_supply[] = {
- REGULATOR_SUPPLY("vcc", "iva.0"),
-};
-
-static struct regulator_consumer_supply omap4_vdd3_supply[] = {
- REGULATOR_SUPPLY("vcc", "l3_main.0"),
-};
-
-static struct regulator_init_data omap4_vdd1 = {
- .constraints = {
- .name = "vdd_mpu",
- .min_uV = 500000,
- .max_uV = 1500000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_vdd1_supply),
- .consumer_supplies = omap4_vdd1_supply,
-};
-
-static struct regulator_init_data omap4_vdd2 = {
- .constraints = {
- .name = "vdd_iva",
- .min_uV = 500000,
- .max_uV = 1500000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_vdd2_supply),
- .consumer_supplies = omap4_vdd2_supply,
-};
-
-static struct regulator_init_data omap4_vdd3 = {
- .constraints = {
- .name = "vdd_core",
- .min_uV = 500000,
- .max_uV = 1500000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_vdd3_supply),
- .consumer_supplies = omap4_vdd3_supply,
-};
-
-
-static struct twl_regulator_driver_data omap4_vdd1_drvdata = {
- .get_voltage = twl_get_voltage,
- .set_voltage = twl_set_voltage,
-};
-
-static struct twl_regulator_driver_data omap4_vdd2_drvdata = {
- .get_voltage = twl_get_voltage,
- .set_voltage = twl_set_voltage,
-};
-
-static struct twl_regulator_driver_data omap4_vdd3_drvdata = {
- .get_voltage = twl_get_voltage,
- .set_voltage = twl_set_voltage,
-};
-
-static struct regulator_consumer_supply omap4_v1v8_supply[] = {
- REGULATOR_SUPPLY("vio", "1-004b"),
-};
-
-static struct regulator_init_data omap4_v1v8_idata = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- .always_on = true,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_v1v8_supply),
- .consumer_supplies = omap4_v1v8_supply,
-};
-
-static struct regulator_consumer_supply omap4_v2v1_supply[] = {
- REGULATOR_SUPPLY("v2v1", "1-004b"),
-};
-
-static struct regulator_init_data omap4_v2v1_idata = {
- .constraints = {
- .min_uV = 2100000,
- .max_uV = 2100000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(omap4_v2v1_supply),
- .consumer_supplies = omap4_v2v1_supply,
-};
-
-void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
- u32 pdata_flags, u32 regulators_flags)
-{
- if (!pmic_data->vdd1) {
- omap4_vdd1.driver_data = &omap4_vdd1_drvdata;
- omap4_vdd1_drvdata.data = voltdm_lookup("mpu");
- pmic_data->vdd1 = &omap4_vdd1;
- }
-
- if (!pmic_data->vdd2) {
- omap4_vdd2.driver_data = &omap4_vdd2_drvdata;
- omap4_vdd2_drvdata.data = voltdm_lookup("iva");
- pmic_data->vdd2 = &omap4_vdd2;
- }
-
- if (!pmic_data->vdd3) {
- omap4_vdd3.driver_data = &omap4_vdd3_drvdata;
- omap4_vdd3_drvdata.data = voltdm_lookup("core");
- pmic_data->vdd3 = &omap4_vdd3;
- }
-
- /* Common platform data configurations */
- if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb)
- pmic_data->usb = &omap4_usb_pdata;
-
- /* Common regulator configurations */
- if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac)
- pmic_data->vdac = &omap4_vdac_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VAUX2 && !pmic_data->vaux2)
- pmic_data->vaux2 = &omap4_vaux2_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VAUX3 && !pmic_data->vaux3)
- pmic_data->vaux3 = &omap4_vaux3_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VMMC && !pmic_data->vmmc)
- pmic_data->vmmc = &omap4_vmmc_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VPP && !pmic_data->vpp)
- pmic_data->vpp = &omap4_vpp_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VANA && !pmic_data->vana)
- pmic_data->vana = &omap4_vana_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VCXIO && !pmic_data->vcxio)
- pmic_data->vcxio = &omap4_vcxio_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_VUSB && !pmic_data->vusb)
- pmic_data->vusb = &omap4_vusb_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_CLK32KG &&
- !pmic_data->clk32kg)
- pmic_data->clk32kg = &omap4_clk32kg_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_V1V8 && !pmic_data->v1v8)
- pmic_data->v1v8 = &omap4_v1v8_idata;
-
- if (regulators_flags & TWL_COMMON_REGULATOR_V2V1 && !pmic_data->v2v1)
- pmic_data->v2v1 = &omap4_v2v1_idata;
-}
-#endif /* CONFIG_ARCH_OMAP4 */
-
-#if IS_ENABLED(CONFIG_SND_OMAP_SOC_OMAP_TWL4030)
-#include <linux/platform_data/omap-twl4030.h>
-
-/* Commonly used configuration */
-static struct omap_tw4030_pdata omap_twl4030_audio_data;
-
-static struct platform_device audio_device = {
- .name = "omap-twl4030",
- .id = -1,
-};
-
-void omap_twl4030_audio_init(char *card_name,
- struct omap_tw4030_pdata *pdata)
-{
- if (!pdata)
- pdata = &omap_twl4030_audio_data;
-
- pdata->card_name = card_name;
-
- audio_device.dev.platform_data = pdata;
- platform_device_register(&audio_device);
-}
-
-#else /* SOC_OMAP_TWL4030 */
-void omap_twl4030_audio_init(char *card_name,
- struct omap_tw4030_pdata *pdata)
-{
- return;
-}
-#endif /* SOC_OMAP_TWL4030 */
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h
deleted file mode 100644
index 24b65d081b69..000000000000
--- a/arch/arm/mach-omap2/twl-common.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef __OMAP_PMIC_COMMON__
-#define __OMAP_PMIC_COMMON__
-
-#include "common.h"
-
-#define TWL_COMMON_PDATA_USB (1 << 0)
-#define TWL_COMMON_PDATA_BCI (1 << 1)
-#define TWL_COMMON_PDATA_MADC (1 << 2)
-#define TWL_COMMON_PDATA_AUDIO (1 << 3)
-
-/* Common LDO regulators for TWL4030/TWL6030 */
-#define TWL_COMMON_REGULATOR_VDAC (1 << 0)
-#define TWL_COMMON_REGULATOR_VAUX1 (1 << 1)
-#define TWL_COMMON_REGULATOR_VAUX2 (1 << 2)
-#define TWL_COMMON_REGULATOR_VAUX3 (1 << 3)
-
-/* TWL6030 LDO regulators */
-#define TWL_COMMON_REGULATOR_VMMC (1 << 4)
-#define TWL_COMMON_REGULATOR_VPP (1 << 5)
-#define TWL_COMMON_REGULATOR_VUSIM (1 << 6)
-#define TWL_COMMON_REGULATOR_VANA (1 << 7)
-#define TWL_COMMON_REGULATOR_VCXIO (1 << 8)
-#define TWL_COMMON_REGULATOR_VUSB (1 << 9)
-#define TWL_COMMON_REGULATOR_CLK32KG (1 << 10)
-#define TWL_COMMON_REGULATOR_V1V8 (1 << 11)
-#define TWL_COMMON_REGULATOR_V2V1 (1 << 12)
-
-/* TWL4030 LDO regulators */
-#define TWL_COMMON_REGULATOR_VPLL1 (1 << 4)
-#define TWL_COMMON_REGULATOR_VPLL2 (1 << 5)
-
-
-struct twl4030_platform_data;
-struct twl6040_platform_data;
-struct omap_tw4030_pdata;
-struct i2c_board_info;
-
-void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
- struct twl4030_platform_data *pmic_data);
-void omap_pmic_late_init(void);
-
-static inline void omap2_pmic_init(const char *pmic_type,
- struct twl4030_platform_data *pmic_data)
-{
- omap_pmic_init(2, 2600, pmic_type, 7 + OMAP_INTC_START, pmic_data);
-}
-
-static inline void omap3_pmic_init(const char *pmic_type,
- struct twl4030_platform_data *pmic_data)
-{
- omap_pmic_init(1, 2600, pmic_type, 7 + OMAP_INTC_START, pmic_data);
-}
-
-void omap4_pmic_init(const char *pmic_type,
- struct twl4030_platform_data *pmic_data,
- struct i2c_board_info *devices, int nr_devices);
-
-void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
- u32 pdata_flags, u32 regulators_flags);
-
-void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
- u32 pdata_flags, u32 regulators_flags);
-
-void omap_twl4030_audio_init(char *card_name, struct omap_tw4030_pdata *pdata);
-
-#endif /* __OMAP_PMIC_COMMON__ */
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
deleted file mode 100644
index 745367c0c2bb..000000000000
--- a/arch/arm/mach-omap2/usb-host.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * usb-host.c - OMAP USB Host
- *
- * This file will contain the board specific details for the
- * Synopsys EHCI/OHCI host controller on OMAP3430 and onwards
- *
- * Copyright (C) 2007-2011 Texas Instruments
- * Author: Vikram Pandita <vikram.pandita@ti.com>
- * Author: Keshava Munegowda <keshava_mgowda@ti.com>
- *
- * Generalization by:
- * Felipe Balbi <balbi@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/string.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/usb_phy_generic.h>
-
-#include "soc.h"
-#include "omap_device.h"
-#include "mux.h"
-#include "usb.h"
-
-#ifdef CONFIG_MFD_OMAP_USB_HOST
-
-#define OMAP_USBHS_DEVICE "usbhs_omap"
-#define OMAP_USBTLL_DEVICE "usbhs_tll"
-#define USBHS_UHH_HWMODNAME "usb_host_hs"
-#define USBHS_TLL_HWMODNAME "usb_tll_hs"
-
-/* MUX settings for EHCI pins */
-/*
- * setup_ehci_io_mux - initialize IO pad mux for USBHOST
- */
-static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
-{
- switch (port_mode[0]) {
- case OMAP_EHCI_PORT_MODE_PHY:
- omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_EHCI_PORT_MODE_TLL:
- omap_mux_init_signal("hsusb1_tll_stp",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hsusb1_tll_clk",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_dir",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_nxt",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data1",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data2",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data3",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data4",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data5",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data6",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb1_tll_data7",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_USBHS_PORT_MODE_UNUSED:
- /* FALLTHROUGH */
- default:
- break;
- }
-
- switch (port_mode[1]) {
- case OMAP_EHCI_PORT_MODE_PHY:
- omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data1",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data2",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data3",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data4",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data5",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data6",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_data7",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_EHCI_PORT_MODE_TLL:
- omap_mux_init_signal("hsusb2_tll_stp",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hsusb2_tll_clk",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_dir",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_nxt",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data1",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data2",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data3",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data4",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data5",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data6",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb2_tll_data7",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_USBHS_PORT_MODE_UNUSED:
- /* FALLTHROUGH */
- default:
- break;
- }
-
- switch (port_mode[2]) {
- case OMAP_EHCI_PORT_MODE_PHY:
- printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
- break;
- case OMAP_EHCI_PORT_MODE_TLL:
- omap_mux_init_signal("hsusb3_tll_stp",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hsusb3_tll_clk",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_dir",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_nxt",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data1",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data2",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data3",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data4",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data5",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data6",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("hsusb3_tll_data7",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_USBHS_PORT_MODE_UNUSED:
- /* FALLTHROUGH */
- default:
- break;
- }
-
- return;
-}
-
-static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
-{
- switch (port_mode[0]) {
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
- omap_mux_init_signal("mm1_rxdp",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("mm1_rxdm",
- OMAP_PIN_INPUT_PULLDOWN);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
- case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
- omap_mux_init_signal("mm1_rxrcv",
- OMAP_PIN_INPUT_PULLDOWN);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
- omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
- omap_mux_init_signal("mm1_txse0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("mm1_txdat",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_USBHS_PORT_MODE_UNUSED:
- /* FALLTHROUGH */
- default:
- break;
- }
- switch (port_mode[1]) {
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
- omap_mux_init_signal("mm2_rxdp",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("mm2_rxdm",
- OMAP_PIN_INPUT_PULLDOWN);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
- case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
- omap_mux_init_signal("mm2_rxrcv",
- OMAP_PIN_INPUT_PULLDOWN);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
- omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
- omap_mux_init_signal("mm2_txse0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("mm2_txdat",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_USBHS_PORT_MODE_UNUSED:
- /* FALLTHROUGH */
- default:
- break;
- }
- switch (port_mode[2]) {
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
- omap_mux_init_signal("mm3_rxdp",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("mm3_rxdm",
- OMAP_PIN_INPUT_PULLDOWN);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
- case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
- omap_mux_init_signal("mm3_rxrcv",
- OMAP_PIN_INPUT_PULLDOWN);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
- omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
- /* FALLTHROUGH */
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
- omap_mux_init_signal("mm3_txse0",
- OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_signal("mm3_txdat",
- OMAP_PIN_INPUT_PULLDOWN);
- break;
- case OMAP_USBHS_PORT_MODE_UNUSED:
- /* FALLTHROUGH */
- default:
- break;
- }
-}
-
-void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
-{
- struct omap_hwmod *uhh_hwm, *tll_hwm;
- struct platform_device *pdev;
- int bus_id = -1;
-
- if (cpu_is_omap34xx()) {
- setup_ehci_io_mux(pdata->port_mode);
- setup_ohci_io_mux(pdata->port_mode);
-
- if (omap_rev() <= OMAP3430_REV_ES2_1)
- pdata->single_ulpi_bypass = true;
-
- }
-
- uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
- if (!uhh_hwm) {
- pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
- return;
- }
-
- tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
- if (!tll_hwm) {
- pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
- return;
- }
-
- pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
- pdata, sizeof(*pdata));
- if (IS_ERR(pdev)) {
- pr_err("Could not build hwmod device %s\n",
- USBHS_TLL_HWMODNAME);
- return;
- }
-
- pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
- pdata, sizeof(*pdata));
- if (IS_ERR(pdev)) {
- pr_err("Could not build hwmod devices %s\n",
- USBHS_UHH_HWMODNAME);
- return;
- }
-}
-
-#else
-
-void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
-{
-}
-
-#endif
-
-/* Template for PHY regulators */
-static struct fixed_voltage_config hsusb_reg_config = {
- /* .supply_name filled later */
- .microvolts = 3300000,
- .gpio = -1, /* updated later */
- .startup_delay = 70000, /* 70msec */
- .enable_high = 1, /* updated later */
- .enabled_at_boot = 0, /* keep in RESET */
- /* .init_data filled later */
-};
-
-static const char *nop_name = "usb_phy_generic"; /* NOP PHY driver */
-static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
-
-/**
- * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
- * @name: name for the regulator
- * @dev_id: device id of the device this regulator supplies power to
- * @dev_supply: supply name that the device expects
- * @gpio: GPIO number
- * @polarity: 1 - Active high, 0 - Active low
- */
-static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
- int gpio, int polarity)
-{
- struct regulator_consumer_supply *supplies;
- struct regulator_init_data *reg_data;
- struct fixed_voltage_config *config;
- struct platform_device *pdev;
- struct platform_device_info pdevinfo;
- int ret = -ENOMEM;
-
- supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
- if (!supplies)
- return -ENOMEM;
-
- supplies->supply = dev_supply;
- supplies->dev_name = dev_id;
-
- reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
- if (!reg_data)
- goto err_data;
-
- reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
- reg_data->consumer_supplies = supplies;
- reg_data->num_consumer_supplies = 1;
-
- config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
- GFP_KERNEL);
- if (!config)
- goto err_config;
-
- config->supply_name = kstrdup(name, GFP_KERNEL);
- if (!config->supply_name)
- goto err_supplyname;
-
- config->gpio = gpio;
- config->enable_high = polarity;
- config->init_data = reg_data;
-
- /* create a regulator device */
- memset(&pdevinfo, 0, sizeof(pdevinfo));
- pdevinfo.name = reg_name;
- pdevinfo.id = PLATFORM_DEVID_AUTO;
- pdevinfo.data = config;
- pdevinfo.size_data = sizeof(*config);
-
- pdev = platform_device_register_full(&pdevinfo);
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- pr_err("%s: Failed registering regulator %s for %s : %d\n",
- __func__, name, dev_id, ret);
- goto err_register;
- }
-
- return 0;
-
-err_register:
- kfree(config->supply_name);
-err_supplyname:
- kfree(config);
-err_config:
- kfree(reg_data);
-err_data:
- kfree(supplies);
- return ret;
-}
-
-#define MAX_STR 20
-
-int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
-{
- char rail_name[MAX_STR];
- int i;
- struct platform_device *pdev;
- char *phy_id;
- struct platform_device_info pdevinfo;
- struct usb_phy_generic_platform_data nop_pdata;
-
- for (i = 0; i < num_phys; i++) {
-
- if (!phy->port) {
- pr_err("%s: Invalid port 0. Must start from 1\n",
- __func__);
- continue;
- }
-
- /* do we need a NOP PHY device ? */
- if (!gpio_is_valid(phy->reset_gpio) &&
- !gpio_is_valid(phy->vcc_gpio))
- continue;
-
- phy_id = kmalloc(MAX_STR, GFP_KERNEL);
- if (!phy_id) {
- pr_err("%s: kmalloc() failed\n", __func__);
- return -ENOMEM;
- }
-
- /* set platform data */
- memset(&nop_pdata, 0, sizeof(nop_pdata));
- if (gpio_is_valid(phy->vcc_gpio))
- nop_pdata.needs_vcc = true;
- nop_pdata.gpio_reset = phy->reset_gpio;
- nop_pdata.type = USB_PHY_TYPE_USB2;
-
- /* create a NOP PHY device */
- memset(&pdevinfo, 0, sizeof(pdevinfo));
- pdevinfo.name = nop_name;
- pdevinfo.id = phy->port;
- pdevinfo.data = &nop_pdata;
- pdevinfo.size_data =
- sizeof(struct usb_phy_generic_platform_data);
- scnprintf(phy_id, MAX_STR, "usb_phy_generic.%d",
- phy->port);
- pdev = platform_device_register_full(&pdevinfo);
- if (IS_ERR(pdev)) {
- pr_err("%s: Failed to register device %s : %ld\n",
- __func__, phy_id, PTR_ERR(pdev));
- kfree(phy_id);
- continue;
- }
-
- usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
-
- /* Do we need VCC regulator ? */
- if (gpio_is_valid(phy->vcc_gpio)) {
- scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port);
- usbhs_add_regulator(rail_name, phy_id, "vcc",
- phy->vcc_gpio, phy->vcc_polarity);
- }
-
- phy++;
- }
-
- return 0;
-}
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
deleted file mode 100644
index e4562b2b973b..000000000000
--- a/arch/arm/mach-omap2/usb-musb.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/usb-musb.c
- *
- * This file will contain the board specific details for the
- * MENTOR USB OTG controller on OMAP3430
- *
- * Copyright (C) 2007-2008 Texas Instruments
- * Copyright (C) 2008 Nokia Corporation
- * Author: Vikram Pandita
- *
- * Generalization by:
- * Felipe Balbi <felipe.balbi@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/types.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/io.h>
-#include <linux/usb/musb.h>
-
-#include "omap_device.h"
-#include "soc.h"
-#include "mux.h"
-#include "usb.h"
-
-static struct musb_hdrc_config musb_config = {
- .multipoint = 1,
- .dyn_fifo = 1,
- .num_eps = 16,
- .ram_bits = 12,
-};
-
-static struct musb_hdrc_platform_data musb_plat = {
- .mode = MUSB_OTG,
-
- /* .clock is set dynamically */
- .config = &musb_config,
-
- /* REVISIT charge pump on TWL4030 can supply up to
- * 100 mA ... but this value is board-specific, like
- * "mode", and should be passed to usb_musb_init().
- */
- .power = 50, /* up to 100 mA */
-};
-
-static u64 musb_dmamask = DMA_BIT_MASK(32);
-
-static struct omap_musb_board_data musb_default_board_data = {
- .interface_type = MUSB_INTERFACE_ULPI,
- .mode = MUSB_OTG,
- .power = 100,
-};
-
-void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
-{
- struct omap_hwmod *oh;
- struct platform_device *pdev;
- struct device *dev;
- int bus_id = -1;
- const char *oh_name, *name;
- struct omap_musb_board_data *board_data;
-
- if (musb_board_data)
- board_data = musb_board_data;
- else
- board_data = &musb_default_board_data;
-
- /*
- * REVISIT: This line can be removed once all the platforms using
- * musb_core.c have been converted to use use clkdev.
- */
- musb_plat.clock = "ick";
- musb_plat.board_data = board_data;
- musb_plat.power = board_data->power >> 1;
- musb_plat.mode = board_data->mode;
- musb_plat.extvbus = board_data->extvbus;
-
- oh_name = "usb_otg_hs";
- name = "musb-omap2430";
-
- oh = omap_hwmod_lookup(oh_name);
- if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
- __func__, oh_name))
- return;
-
- pdev = omap_device_build(name, bus_id, oh, &musb_plat,
- sizeof(musb_plat));
- if (IS_ERR(pdev)) {
- pr_err("Could not build omap_device for %s %s\n",
- name, oh_name);
- return;
- }
-
- dev = &pdev->dev;
- get_device(dev);
- dev->dma_mask = &musb_dmamask;
- dev->coherent_dma_mask = musb_dmamask;
- put_device(dev);
-}
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index e554d9e66a1c..c2a6fbd7f8a9 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -22,8 +22,6 @@
#include "gpmc.h"
-#include "mux.h"
-
static u8 async_cs, sync_cs;
static unsigned refclk_psec;
@@ -226,25 +224,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
}
tusb_device.dev.platform_data = data;
- /* REVISIT let the driver know what DMA channels work */
- if (!dmachan)
- tusb_device.dev.dma_mask = NULL;
- else {
- /* assume OMAP 2420 ES2.0 and later */
- if (dmachan & (1 << 0))
- omap_mux_init_signal("sys_ndmareq0", 0);
- if (dmachan & (1 << 1))
- omap_mux_init_signal("sys_ndmareq1", 0);
- if (dmachan & (1 << 2))
- omap_mux_init_signal("sys_ndmareq2", 0);
- if (dmachan & (1 << 3))
- omap_mux_init_signal("sys_ndmareq3", 0);
- if (dmachan & (1 << 4))
- omap_mux_init_signal("sys_ndmareq4", 0);
- if (dmachan & (1 << 5))
- omap_mux_init_signal("sys_ndmareq5", 0);
- }
-
/* so far so good ... register the device */
status = platform_device_register(&tusb_device);
if (status < 0) {
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 89bb0fc796bd..633442ad4e4c 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -84,13 +84,6 @@ config MACH_LINKSTATION_PRO
Buffalo Linkstation Pro/Live platform. Both v1 and
v2 devices are supported.
-config MACH_LINKSTATION_LSCHL
- bool "Buffalo Linkstation Live v3 (LS-CHL)"
- select I2C_BOARDINFO if I2C
- help
- Say 'Y' here if you want your kernel to support the
- Buffalo Linkstation Live v3 (LS-CHL) platform.
-
config MACH_LINKSTATION_MINI
bool "Buffalo Linkstation Mini (Flattened Device Tree)"
select ARCH_ORION5X_DT
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index 4b2502b4ca0d..ae91872eeee4 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o
obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o
-obj-$(CONFIG_MACH_LINKSTATION_LSCHL) += ls-chl-setup.o
obj-$(CONFIG_ARCH_ORION5X_DT) += board-dt.o
obj-$(CONFIG_MACH_D2NET_DT) += board-d2net.o
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c
deleted file mode 100644
index dfdaa8a498a4..000000000000
--- a/arch/arm/mach-orion5x/ls-chl-setup.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * arch/arm/mach-orion5x/ls-chl-setup.c
- *
- * Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk>
- *
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/leds.h>
-#include <linux/gpio_keys.h>
-#include <linux/gpio-fan.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/ata_platform.h>
-#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include "common.h"
-#include "mpp.h"
-#include "orion5x.h"
-
-/*****************************************************************************
- * Linkstation LS-CHL Info
- ****************************************************************************/
-
-/*
- * 256K NOR flash Device bus boot chip select
- */
-
-#define LSCHL_NOR_BOOT_BASE 0xf4000000
-#define LSCHL_NOR_BOOT_SIZE SZ_256K
-
-/*****************************************************************************
- * 256KB NOR Flash on BOOT Device
- ****************************************************************************/
-
-static struct physmap_flash_data lschl_nor_flash_data = {
- .width = 1,
-};
-
-static struct resource lschl_nor_flash_resource = {
- .flags = IORESOURCE_MEM,
- .start = LSCHL_NOR_BOOT_BASE,
- .end = LSCHL_NOR_BOOT_BASE + LSCHL_NOR_BOOT_SIZE - 1,
-};
-
-static struct platform_device lschl_nor_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &lschl_nor_flash_data,
- },
- .num_resources = 1,
- .resource = &lschl_nor_flash_resource,
-};
-
-/*****************************************************************************
- * Ethernet
- ****************************************************************************/
-
-static struct mv643xx_eth_platform_data lschl_eth_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
-/*****************************************************************************
- * RTC 5C372a on I2C bus
- ****************************************************************************/
-
-static struct i2c_board_info __initdata lschl_i2c_rtc = {
- I2C_BOARD_INFO("rs5c372a", 0x32),
-};
-
-/*****************************************************************************
- * LEDs attached to GPIO
- ****************************************************************************/
-
-#define LSCHL_GPIO_LED_ALARM 2
-#define LSCHL_GPIO_LED_INFO 3
-#define LSCHL_GPIO_LED_FUNC 17
-#define LSCHL_GPIO_LED_PWR 0
-
-static struct gpio_led lschl_led_pins[] = {
- {
- .name = "alarm:red",
- .gpio = LSCHL_GPIO_LED_ALARM,
- .active_low = 1,
- }, {
- .name = "info:amber",
- .gpio = LSCHL_GPIO_LED_INFO,
- .active_low = 1,
- }, {
- .name = "func:blue:top",
- .gpio = LSCHL_GPIO_LED_FUNC,
- .active_low = 1,
- }, {
- .name = "power:blue:bottom",
- .gpio = LSCHL_GPIO_LED_PWR,
- },
-};
-
-static struct gpio_led_platform_data lschl_led_data = {
- .leds = lschl_led_pins,
- .num_leds = ARRAY_SIZE(lschl_led_pins),
-};
-
-static struct platform_device lschl_leds = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &lschl_led_data,
- },
-};
-
-/*****************************************************************************
- * SATA
- ****************************************************************************/
-static struct mv_sata_platform_data lschl_sata_data = {
- .n_ports = 2,
-};
-
-/*****************************************************************************
- * LS-CHL specific power off method: reboot
- ****************************************************************************/
-/*
- * On the LS-CHL, the shutdown process is following:
- * - Userland monitors key events until the power switch goes to off position
- * - The board reboots
- * - U-boot starts and goes into an idle mode waiting for the user
- * to move the switch to ON position
- *
- */
-
-static void lschl_power_off(void)
-{
- orion5x_restart(REBOOT_HARD, NULL);
-}
-
-/*****************************************************************************
- * General Setup
- ****************************************************************************/
-#define LSCHL_GPIO_USB_POWER 9
-#define LSCHL_GPIO_AUTO_POWER 17
-#define LSCHL_GPIO_POWER 18
-
-/****************************************************************************
- * GPIO Attached Keys
- ****************************************************************************/
-#define LSCHL_GPIO_KEY_FUNC 15
-#define LSCHL_GPIO_KEY_POWER 8
-#define LSCHL_GPIO_KEY_AUTOPOWER 10
-#define LSCHL_SW_POWER 0x00
-#define LSCHL_SW_AUTOPOWER 0x01
-#define LSCHL_SW_FUNC 0x02
-
-static struct gpio_keys_button lschl_buttons[] = {
- {
- .type = EV_SW,
- .code = LSCHL_SW_POWER,
- .gpio = LSCHL_GPIO_KEY_POWER,
- .desc = "Power-on Switch",
- .active_low = 1,
- }, {
- .type = EV_SW,
- .code = LSCHL_SW_AUTOPOWER,
- .gpio = LSCHL_GPIO_KEY_AUTOPOWER,
- .desc = "Power-auto Switch",
- .active_low = 1,
- }, {
- .type = EV_SW,
- .code = LSCHL_SW_FUNC,
- .gpio = LSCHL_GPIO_KEY_FUNC,
- .desc = "Function Switch",
- .active_low = 1,
- },
-};
-
-static struct gpio_keys_platform_data lschl_button_data = {
- .buttons = lschl_buttons,
- .nbuttons = ARRAY_SIZE(lschl_buttons),
-};
-
-static struct platform_device lschl_button_device = {
- .name = "gpio-keys",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &lschl_button_data,
- },
-};
-
-#define LSCHL_GPIO_HDD_POWER 1
-
-/****************************************************************************
- * GPIO Fan
- ****************************************************************************/
-
-#define LSCHL_GPIO_FAN_LOW 16
-#define LSCHL_GPIO_FAN_HIGH 14
-#define LSCHL_GPIO_FAN_LOCK 6
-
-static struct gpio_fan_alarm lschl_alarm = {
- .gpio = LSCHL_GPIO_FAN_LOCK,
-};
-
-static struct gpio_fan_speed lschl_speeds[] = {
- {
- .rpm = 0,
- .ctrl_val = 3,
- }, {
- .rpm = 1500,
- .ctrl_val = 2,
- }, {
- .rpm = 3250,
- .ctrl_val = 1,
- }, {
- .rpm = 5000,
- .ctrl_val = 0,
- },
-};
-
-static int lschl_gpio_list[] = {
- LSCHL_GPIO_FAN_HIGH, LSCHL_GPIO_FAN_LOW,
-};
-
-static struct gpio_fan_platform_data lschl_fan_data = {
- .num_ctrl = ARRAY_SIZE(lschl_gpio_list),
- .ctrl = lschl_gpio_list,
- .alarm = &lschl_alarm,
- .num_speed = ARRAY_SIZE(lschl_speeds),
- .speed = lschl_speeds,
-};
-
-static struct platform_device lschl_fan_device = {
- .name = "gpio-fan",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &lschl_fan_data,
- },
-};
-
-/****************************************************************************
- * GPIO Data
- ****************************************************************************/
-
-static unsigned int lschl_mpp_modes[] __initdata = {
- MPP0_GPIO, /* LED POWER */
- MPP1_GPIO, /* HDD POWER */
- MPP2_GPIO, /* LED ALARM */
- MPP3_GPIO, /* LED INFO */
- MPP4_UNUSED,
- MPP5_UNUSED,
- MPP6_GPIO, /* FAN LOCK */
- MPP7_GPIO, /* SW INIT */
- MPP8_GPIO, /* SW POWER */
- MPP9_GPIO, /* USB POWER */
- MPP10_GPIO, /* SW AUTO POWER */
- MPP11_UNUSED,
- MPP12_UNUSED,
- MPP13_UNUSED,
- MPP14_GPIO, /* FAN HIGH */
- MPP15_GPIO, /* SW FUNC */
- MPP16_GPIO, /* FAN LOW */
- MPP17_GPIO, /* LED FUNC */
- MPP18_UNUSED,
- MPP19_UNUSED,
- 0,
-};
-
-static void __init lschl_init(void)
-{
- /*
- * Setup basic Orion functions. Needs to be called early.
- */
- orion5x_init();
-
- orion5x_mpp_conf(lschl_mpp_modes);
-
- /*
- * Configure peripherals.
- */
- orion5x_ehci0_init();
- orion5x_ehci1_init();
- orion5x_eth_init(&lschl_eth_data);
- orion5x_i2c_init();
- orion5x_sata_init(&lschl_sata_data);
- orion5x_uart0_init();
- orion5x_xor_init();
-
- mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
- ORION_MBUS_DEVBUS_BOOT_ATTR,
- LSCHL_NOR_BOOT_BASE,
- LSCHL_NOR_BOOT_SIZE);
- platform_device_register(&lschl_nor_flash);
-
- platform_device_register(&lschl_leds);
-
- platform_device_register(&lschl_button_device);
-
- platform_device_register(&lschl_fan_device);
-
- i2c_register_board_info(0, &lschl_i2c_rtc, 1);
-
- /* usb power on */
- gpio_set_value(LSCHL_GPIO_USB_POWER, 1);
-
- /* register power-off method */
- pm_power_off = lschl_power_off;
-
- pr_info("%s: finished\n", __func__);
-}
-
-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,
- .init_irq = orion5x_init_irq,
- .init_time = orion5x_timer_init,
- .fixup = tag_fixup_mem32,
- .restart = orion5x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-oxnas/Kconfig b/arch/arm/mach-oxnas/Kconfig
index 29100beb2e7f..8fa4557e27a9 100644
--- a/arch/arm/mach-oxnas/Kconfig
+++ b/arch/arm/mach-oxnas/Kconfig
@@ -1,9 +1,16 @@
menuconfig ARCH_OXNAS
bool "Oxford Semiconductor OXNAS Family SoCs"
select ARCH_HAS_RESET_CONTROLLER
+ select COMMON_CLK_OXNAS
select GPIOLIB
+ select MFD_SYSCON
+ select OXNAS_RPS_TIMER
+ select PINCTRL_OXNAS
+ select RESET_CONTROLLER
+ select RESET_OXNAS
+ select VERSATILE_FPGA_IRQ
select PINCTRL
- depends on ARCH_MULTI_V5
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
help
Support for OxNas SoC family developed by Oxford Semiconductor.
@@ -11,16 +18,21 @@ if ARCH_OXNAS
config MACH_OX810SE
bool "Support OX810SE Based Products"
- select ARCH_HAS_RESET_CONTROLLER
- select COMMON_CLK_OXNAS
+ depends on ARCH_MULTI_V5
select CPU_ARM926T
- select MFD_SYSCON
- select OXNAS_RPS_TIMER
- select PINCTRL_OXNAS
- select RESET_CONTROLLER
- select RESET_OXNAS
- select VERSATILE_FPGA_IRQ
help
Include Support for the Oxford Semiconductor OX810SE SoC Based Products.
+config MACH_OX820
+ bool "Support OX820 Based Products"
+ depends on ARCH_MULTI_V6
+ select ARM_GIC
+ select DMA_CACHE_RWFO if SMP
+ select CPU_V6K
+ select HAVE_SMP
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ help
+ Include Support for the Oxford Semiconductor OX820 SoC Based Products.
+
endif
diff --git a/arch/arm/mach-oxnas/Makefile b/arch/arm/mach-oxnas/Makefile
new file mode 100644
index 000000000000..b625906a9970
--- /dev/null
+++ b/arch/arm/mach-oxnas/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-oxnas/headsmp.S b/arch/arm/mach-oxnas/headsmp.S
new file mode 100644
index 000000000000..25fd4f82ab3a
--- /dev/null
+++ b/arch/arm/mach-oxnas/headsmp.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
+ * Copyright (c) 2003 ARM Limited
+ * 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 <linux/linkage.h>
+#include <linux/init.h>
+
+ __INIT
+
+/*
+ * OX820 specific entry point for secondary CPUs.
+ */
+ENTRY(ox820_secondary_startup)
+ mov r4, #0
+ /* invalidate both caches and branch target cache */
+ mcr p15, 0, r4, c7, c7, 0
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
diff --git a/arch/arm/mach-oxnas/hotplug.c b/arch/arm/mach-oxnas/hotplug.c
new file mode 100644
index 000000000000..854f29b8cba6
--- /dev/null
+++ b/arch/arm/mach-oxnas/hotplug.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2002 ARM 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C)
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+ /*
+ * there is no power-control hardware on this platform, so all
+ * we can do is put the core into WFI; this is safe as the calling
+ * code will have already disabled interrupts
+ */
+ for (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu_logical_map(cpu)) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void ox820_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
diff --git a/arch/arm/mach-oxnas/platsmp.c b/arch/arm/mach-oxnas/platsmp.c
new file mode 100644
index 000000000000..442cc8a2f7dc
--- /dev/null
+++ b/arch/arm/mach-oxnas/platsmp.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
+ * Copyright (C) 2002 ARM 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+extern void ox820_secondary_startup(void);
+extern void ox820_cpu_die(unsigned int cpu);
+
+static void __iomem *cpu_ctrl;
+static void __iomem *gic_cpu_ctrl;
+
+#define HOLDINGPEN_CPU_OFFSET 0xc8
+#define HOLDINGPEN_LOCATION_OFFSET 0xc4
+
+#define GIC_NCPU_OFFSET(cpu) (0x100 + (cpu)*0x100)
+#define GIC_CPU_CTRL 0x00
+#define GIC_CPU_CTRL_ENABLE 1
+
+int __init ox820_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ /*
+ * Write the address of secondary startup into the
+ * system-wide flags register. The BootMonitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
+ */
+ writel(virt_to_phys(ox820_secondary_startup),
+ cpu_ctrl + HOLDINGPEN_LOCATION_OFFSET);
+
+ writel(cpu, cpu_ctrl + HOLDINGPEN_CPU_OFFSET);
+
+ /*
+ * Enable GIC cpu interface in CPU Interface Control Register
+ */
+ writel(GIC_CPU_CTRL_ENABLE,
+ gic_cpu_ctrl + GIC_NCPU_OFFSET(cpu) + GIC_CPU_CTRL);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
+ */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ return 0;
+}
+
+static void __init ox820_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *np;
+ void __iomem *scu_base;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,arm11mp-scu");
+ scu_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!scu_base)
+ return;
+
+ /* Remap CPU Interrupt Interface Registers */
+ np = of_find_compatible_node(NULL, NULL, "arm,arm11mp-gic");
+ gic_cpu_ctrl = of_iomap(np, 1);
+ of_node_put(np);
+ if (!gic_cpu_ctrl)
+ goto unmap_scu;
+
+ np = of_find_compatible_node(NULL, NULL, "oxsemi,ox820-sys-ctrl");
+ cpu_ctrl = of_iomap(np, 0);
+ of_node_put(np);
+ if (!cpu_ctrl)
+ goto unmap_scu;
+
+ scu_enable(scu_base);
+ flush_cache_all();
+
+unmap_scu:
+ iounmap(scu_base);
+}
+
+static const struct smp_operations ox820_smp_ops __initconst = {
+ .smp_prepare_cpus = ox820_smp_prepare_cpus,
+ .smp_boot_secondary = ox820_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = ox820_cpu_die,
+#endif
+};
+
+CPU_METHOD_OF_DECLARE(ox820_smp, "oxsemi,ox820-smp", &ox820_smp_ops);
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 10bfdb169366..183cd3446f25 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -35,7 +35,6 @@
#include <linux/mtd/sharpsl.h>
#include <linux/input/matrix_keypad.h>
#include <linux/gpio_keys.h>
-#include <linux/module.h>
#include <linux/memblock.h>
#include <video/w100fb.h>
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 03354c21e1f2..811a7317f3ea 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -23,6 +23,7 @@
#include <linux/gpio.h>
#include <linux/mfd/da903x.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
#include <linux/spi/spi.h>
#include <linux/spi/tdo24m.h>
#include <linux/spi/libertas_spi.h>
@@ -34,8 +35,6 @@
#include <linux/i2c/pxa-i2c.h>
#include <linux/regulator/userspace-consumer.h>
-#include <media/soc_camera.h>
-
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -958,8 +957,6 @@ static inline void em_x270_init_gpio_keys(void) {}
/* Quick Capture Interface and sensor setup */
#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
-static struct regulator *em_x270_camera_ldo;
-
static int em_x270_sensor_init(void)
{
int ret;
@@ -969,81 +966,53 @@ static int em_x270_sensor_init(void)
return ret;
gpio_direction_output(cam_reset, 0);
-
- em_x270_camera_ldo = regulator_get(NULL, "vcc cam");
- if (em_x270_camera_ldo == NULL) {
- gpio_free(cam_reset);
- return -ENODEV;
- }
-
- ret = regulator_enable(em_x270_camera_ldo);
- if (ret) {
- regulator_put(em_x270_camera_ldo);
- gpio_free(cam_reset);
- return ret;
- }
-
gpio_set_value(cam_reset, 1);
return 0;
}
-struct pxacamera_platform_data em_x270_camera_platform_data = {
- .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
- PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
- .mclk_10khz = 2600,
+static struct regulator_consumer_supply camera_dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd", "0-005d"),
};
-static int em_x270_sensor_power(struct device *dev, int on)
-{
- int ret;
- int is_on = regulator_is_enabled(em_x270_camera_ldo);
-
- if (on == is_on)
- return 0;
-
- gpio_set_value(cam_reset, !on);
-
- if (on)
- ret = regulator_enable(em_x270_camera_ldo);
- else
- ret = regulator_disable(em_x270_camera_ldo);
-
- if (ret)
- return ret;
-
- gpio_set_value(cam_reset, on);
-
- return 0;
-}
-
-static struct i2c_board_info em_x270_i2c_cam_info[] = {
- {
- I2C_BOARD_INFO("mt9m111", 0x48),
+static struct regulator_init_data camera_dummy_initdata = {
+ .consumer_supplies = camera_dummy_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(camera_dummy_supplies),
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
};
-static struct soc_camera_link iclink = {
- .bus_id = 0,
- .power = em_x270_sensor_power,
- .board_info = &em_x270_i2c_cam_info[0],
- .i2c_adapter_id = 0,
+static struct fixed_voltage_config camera_dummy_config = {
+ .supply_name = "camera_vdd",
+ .input_supply = "vcc cam",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .enable_high = 0,
+ .init_data = &camera_dummy_initdata,
};
-static struct platform_device em_x270_camera = {
- .name = "soc-camera-pdrv",
- .id = -1,
+static struct platform_device camera_supply_dummy_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
.dev = {
- .platform_data = &iclink,
+ .platform_data = &camera_dummy_config,
},
};
+struct pxacamera_platform_data em_x270_camera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 2600,
+ .sensor_i2c_adapter_id = 0,
+ .sensor_i2c_address = 0x5d,
+};
+
static void __init em_x270_init_camera(void)
{
- if (em_x270_sensor_init() == 0) {
+ if (em_x270_sensor_init() == 0)
pxa_set_camera_info(&em_x270_camera_platform_data);
- platform_device_register(&em_x270_camera);
- }
+ platform_device_register(&camera_supply_dummy_device);
}
#else
static inline void em_x270_init_camera(void) {}
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 34ad0a89d4a9..0b8300e6fca3 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -17,14 +17,14 @@
#include <linux/delay.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/leds-lp3944.h>
#include <linux/i2c/pxa-i2c.h>
-#include <media/soc_camera.h>
-
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -723,6 +723,42 @@ static struct platform_device a780_gpio_keys = {
};
/* camera */
+static struct regulator_consumer_supply camera_dummy_supplies[] = {
+ REGULATOR_SUPPLY("vdd", "0-005d"),
+};
+
+static struct regulator_init_data camera_dummy_initdata = {
+ .consumer_supplies = camera_dummy_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(camera_dummy_supplies),
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config camera_dummy_config = {
+ .supply_name = "camera_vdd",
+ .microvolts = 2800000,
+ .gpio = GPIO50_nCAM_EN,
+ .enable_high = 0,
+ .init_data = &camera_dummy_initdata,
+};
+
+static struct platform_device camera_supply_dummy_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &camera_dummy_config,
+ },
+};
+static int a780_camera_reset(struct device *dev)
+{
+ gpio_set_value(GPIO19_GEN1_CAM_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO19_GEN1_CAM_RST, 1);
+
+ return 0;
+}
+
static int a780_camera_init(void)
{
int err;
@@ -731,73 +767,36 @@ static int a780_camera_init(void)
* GPIO50_nCAM_EN is active low
* GPIO19_GEN1_CAM_RST is active on rising edge
*/
- err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN");
- if (err) {
- pr_err("%s: Failed to request nCAM_EN\n", __func__);
- goto fail;
- }
-
err = gpio_request(GPIO19_GEN1_CAM_RST, "CAM_RST");
if (err) {
pr_err("%s: Failed to request CAM_RST\n", __func__);
- goto fail_gpio_cam_rst;
+ return err;
}
- gpio_direction_output(GPIO50_nCAM_EN, 1);
gpio_direction_output(GPIO19_GEN1_CAM_RST, 0);
-
- return 0;
-
-fail_gpio_cam_rst:
- gpio_free(GPIO50_nCAM_EN);
-fail:
- return err;
-}
-
-static int a780_camera_power(struct device *dev, int on)
-{
- gpio_set_value(GPIO50_nCAM_EN, !on);
- return 0;
-}
-
-static int a780_camera_reset(struct device *dev)
-{
- gpio_set_value(GPIO19_GEN1_CAM_RST, 0);
- msleep(10);
- gpio_set_value(GPIO19_GEN1_CAM_RST, 1);
+ a780_camera_reset(NULL);
return 0;
}
struct pxacamera_platform_data a780_pxacamera_platform_data = {
.flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
- PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN |
+ PXA_CAMERA_PCP,
.mclk_10khz = 5000,
+ .sensor_i2c_adapter_id = 0,
+ .sensor_i2c_address = 0x5d,
};
-static struct i2c_board_info a780_camera_i2c_board_info = {
- I2C_BOARD_INFO("mt9m111", 0x5d),
-};
-
-static struct soc_camera_link a780_iclink = {
- .bus_id = 0,
- .flags = SOCAM_SENSOR_INVERT_PCLK,
- .i2c_adapter_id = 0,
- .board_info = &a780_camera_i2c_board_info,
- .power = a780_camera_power,
- .reset = a780_camera_reset,
-};
-
-static struct platform_device a780_camera = {
- .name = "soc-camera-pdrv",
- .id = 0,
- .dev = {
- .platform_data = &a780_iclink,
+static struct i2c_board_info a780_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("mt9m111", 0x5d),
},
};
static struct platform_device *a780_devices[] __initdata = {
&a780_gpio_keys,
+ &camera_supply_dummy_device,
};
static void __init a780_init(void)
@@ -811,19 +810,19 @@ static void __init a780_init(void)
pxa_set_stuart_info(NULL);
pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(a780_i2c_board_info));
pxa_set_fb_info(NULL, &ezx_fb_info_1);
pxa_set_keypad_info(&a780_keypad_platform_data);
- if (a780_camera_init() == 0) {
+ if (a780_camera_init() == 0)
pxa_set_camera_info(&a780_pxacamera_platform_data);
- platform_device_register(&a780_camera);
- }
pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a780_devices));
+ regulator_has_full_constraints();
}
MACHINE_START(EZX_A780, "Motorola EZX A780")
@@ -1001,6 +1000,15 @@ static struct platform_device a910_gpio_keys = {
};
/* camera */
+static int a910_camera_reset(struct device *dev)
+{
+ gpio_set_value(GPIO28_GEN2_CAM_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO28_GEN2_CAM_RST, 1);
+
+ return 0;
+}
+
static int a910_camera_init(void)
{
int err;
@@ -1009,68 +1017,25 @@ static int a910_camera_init(void)
* GPIO50_nCAM_EN is active low
* GPIO28_GEN2_CAM_RST is active on rising edge
*/
- err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN");
- if (err) {
- pr_err("%s: Failed to request nCAM_EN\n", __func__);
- goto fail;
- }
-
err = gpio_request(GPIO28_GEN2_CAM_RST, "CAM_RST");
if (err) {
pr_err("%s: Failed to request CAM_RST\n", __func__);
- goto fail_gpio_cam_rst;
+ return err;
}
- gpio_direction_output(GPIO50_nCAM_EN, 1);
gpio_direction_output(GPIO28_GEN2_CAM_RST, 0);
-
- return 0;
-
-fail_gpio_cam_rst:
- gpio_free(GPIO50_nCAM_EN);
-fail:
- return err;
-}
-
-static int a910_camera_power(struct device *dev, int on)
-{
- gpio_set_value(GPIO50_nCAM_EN, !on);
- return 0;
-}
-
-static int a910_camera_reset(struct device *dev)
-{
- gpio_set_value(GPIO28_GEN2_CAM_RST, 0);
- msleep(10);
- gpio_set_value(GPIO28_GEN2_CAM_RST, 1);
+ a910_camera_reset(NULL);
return 0;
}
struct pxacamera_platform_data a910_pxacamera_platform_data = {
.flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
- PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN |
+ PXA_CAMERA_PCP,
.mclk_10khz = 5000,
-};
-
-static struct i2c_board_info a910_camera_i2c_board_info = {
- I2C_BOARD_INFO("mt9m111", 0x5d),
-};
-
-static struct soc_camera_link a910_iclink = {
- .bus_id = 0,
- .i2c_adapter_id = 0,
- .board_info = &a910_camera_i2c_board_info,
- .power = a910_camera_power,
- .reset = a910_camera_reset,
-};
-
-static struct platform_device a910_camera = {
- .name = "soc-camera-pdrv",
- .id = 0,
- .dev = {
- .platform_data = &a910_iclink,
- },
+ .sensor_i2c_adapter_id = 0,
+ .sensor_i2c_address = 0x5d,
};
/* leds-lp3944 */
@@ -1122,10 +1087,14 @@ static struct i2c_board_info __initdata a910_i2c_board_info[] = {
I2C_BOARD_INFO("lp3944", 0x60),
.platform_data = &a910_lp3944_leds,
},
+ {
+ I2C_BOARD_INFO("mt9m111", 0x5d),
+ },
};
static struct platform_device *a910_devices[] __initdata = {
&a910_gpio_keys,
+ &camera_supply_dummy_device,
};
static void __init a910_init(void)
@@ -1145,14 +1114,13 @@ static void __init a910_init(void)
pxa_set_keypad_info(&a910_keypad_platform_data);
- if (a910_camera_init() == 0) {
+ if (a910_camera_init() == 0)
pxa_set_camera_info(&a910_pxacamera_platform_data);
- platform_device_register(&a910_camera);
- }
pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a910_devices));
+ regulator_has_full_constraints();
}
MACHINE_START(EZX_A910, "Motorola EZX A910")
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index ec510ecf8370..cb73a9723d0e 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -43,21 +43,6 @@ void clear_reset_status(unsigned int mask)
}
}
-unsigned long get_clock_tick_rate(void)
-{
- unsigned long clock_tick_rate;
-
- if (cpu_is_pxa25x())
- clock_tick_rate = 3686400;
- else if (machine_is_mainstone())
- clock_tick_rate = 3249600;
- else
- clock_tick_rate = 3250000;
-
- return clock_tick_rate;
-}
-EXPORT_SYMBOL(get_clock_tick_rate);
-
/*
* For non device-tree builds, keep legacy timer init
*/
@@ -69,8 +54,7 @@ void __init pxa_timer_init(void)
pxa27x_clocks_init();
if (cpu_is_pxa3xx())
pxa3xx_clocks_init();
- pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000),
- get_clock_tick_rate());
+ pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000));
}
/*
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index 8d63c211b22f..55064124ca4e 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -303,8 +303,6 @@
*/
extern unsigned int get_memclk_frequency_10khz(void);
-/* return the clock tick rate of the OS timer */
-extern unsigned long get_clock_tick_rate(void);
#endif
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 38a96a193dc4..8a5d0491e73c 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -57,7 +57,6 @@
#include <linux/platform_data/media/camera-pxa.h>
#include <mach/audio.h>
#include <mach/smemc.h>
-#include <media/soc_camera.h>
#include "mioa701.h"
@@ -627,6 +626,8 @@ struct pxacamera_platform_data mioa701_pxacamera_platform_data = {
.flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
.mclk_10khz = 5000,
+ .sensor_i2c_adapter_id = 0,
+ .sensor_i2c_address = 0x5d,
};
static struct i2c_board_info __initdata mioa701_pi2c_devices[] = {
@@ -643,12 +644,6 @@ static struct i2c_board_info mioa701_i2c_devices[] = {
},
};
-static struct soc_camera_link iclink = {
- .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
- .board_info = &mioa701_i2c_devices[0],
- .i2c_adapter_id = 0,
-};
-
struct i2c_pxa_platform_data i2c_pdata = {
.fast_mode = 1,
};
@@ -684,7 +679,6 @@ MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
MIO_SIMPLE_DEV(wm9713_acodec, "wm9713-codec", NULL);
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
-MIO_SIMPLE_DEV(mioa701_camera, "soc-camera-pdrv",&iclink);
static struct platform_device *devices[] __initdata = {
&mioa701_gpio_keys,
@@ -696,7 +690,6 @@ static struct platform_device *devices[] __initdata = {
&power_dev,
&docg3,
&gpio_vbus,
- &mioa701_camera,
&mioa701_board,
};
@@ -761,6 +754,7 @@ static void __init mioa701_machine_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
gsm_init();
+ i2c_register_board_info(0, ARRAY_AND_SIZE(mioa701_i2c_devices));
i2c_register_board_info(1, ARRAY_AND_SIZE(mioa701_pi2c_devices));
pxa_set_i2c_info(&i2c_pdata);
pxa27x_set_i2c_power_info(NULL);
@@ -769,6 +763,7 @@ static void __init mioa701_machine_init(void)
regulator_register_always_on(0, "fixed-5.0V", fixed_5v0_consumers,
ARRAY_SIZE(fixed_5v0_consumers),
5000000);
+ regulator_has_full_constraints();
}
static void mioa701_machine_exit(void)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 12b94357fbc1..c725baf119e1 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -156,7 +156,7 @@ static int __init __init
pxa25x_dt_init_irq(struct device_node *node, struct device_node *parent)
{
pxa_dt_irq_init(pxa25x_set_wake);
- set_handle_irq(ichp_handle_irq);
+ set_handle_irq(icip_handle_irq);
return 0;
}
diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c
index e362f865fcd2..941508585e34 100644
--- a/arch/arm/mach-pxa/pxa_cplds_irqs.c
+++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c
@@ -120,13 +120,9 @@ static int cplds_probe(struct platform_device *pdev)
if (!fpga)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res) {
- fpga->irq = (unsigned int)res->start;
- irqflags = res->flags;
- }
- if (!fpga->irq)
- return -ENODEV;
+ fpga->irq = platform_get_irq(pdev, 0);
+ if (fpga->irq <= 0)
+ return fpga->irq;
base_irq = platform_get_irq(pdev, 1);
if (base_irq < 0)
@@ -142,6 +138,7 @@ static int cplds_probe(struct platform_device *pdev)
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
writel(0, fpga->base + FPGA_IRQ_SET_CLR);
+ irqflags = irq_get_trigger_type(fpga->irq);
ret = devm_request_irq(&pdev->dev, fpga->irq, cplds_irq_handler,
irqflags, dev_name(&pdev->dev), fpga);
if (ret == -ENOSYS)
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 2c150bfc0cd5..67d66c702574 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -31,7 +31,6 @@
#include <linux/input/matrix_keypad.h>
#include <linux/regulator/machine.h>
#include <linux/io.h>
-#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/memblock.h>
diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c
index 89c5a62830a7..261820a855ec 100644
--- a/arch/arm/mach-s3c64xx/pl080.c
+++ b/arch/arm/mach-s3c64xx/pl080.c
@@ -117,6 +117,25 @@ static struct pl08x_channel_data s3c64xx_dma0_info[] = {
}
};
+static const struct dma_slave_map s3c64xx_dma0_slave_map[] = {
+ { "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] },
+ { "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] },
+ { "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] },
+ { "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] },
+ { "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] },
+ { "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] },
+ { "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] },
+ { "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] },
+ { "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] },
+ { "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] },
+ { "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] },
+ { "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] },
+ { "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] },
+ { "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] },
+ { "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] },
+ { "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] },
+};
+
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
@@ -134,6 +153,8 @@ struct pl08x_platform_data s3c64xx_dma0_plat_data = {
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma0_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
+ .slave_map = s3c64xx_dma0_slave_map,
+ .slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
};
static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
@@ -207,6 +228,15 @@ static struct pl08x_channel_data s3c64xx_dma1_info[] = {
},
};
+static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
+ { "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] },
+ { "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] },
+ { "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] },
+ { "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] },
+ { "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] },
+ { "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] },
+};
+
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
@@ -224,6 +254,8 @@ struct pl08x_platform_data s3c64xx_dma1_plat_data = {
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma1_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
+ .slave_map = s3c64xx_dma1_slave_map,
+ .slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
};
static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3e09beddb6e8..2eb00691b07d 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -378,7 +378,7 @@ void __init sa1100_map_io(void)
void __init sa1100_timer_init(void)
{
- pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000), 3686400);
+ pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000));
}
static struct resource irq_resource =
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1101.h b/arch/arm/mach-sa1100/include/mach/SA-1101.h
deleted file mode 100644
index 5d2ad7db991c..000000000000
--- a/arch/arm/mach-sa1100/include/mach/SA-1101.h
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * SA-1101.h
- *
- * Copyright (c) Peter Danielsson 1999
- *
- * Definition of constants related to the sa1101
- * support chip for the sa1100
- *
- */
-
-
-/* Be sure that virtual mapping is defined right */
-#ifndef __ASM_ARCH_HARDWARE_H
-#error You must include hardware.h not SA-1101.h
-#endif
-
-#ifndef SA1101_BASE
-#error You must define SA-1101 physical base address
-#endif
-
-#ifndef LANGUAGE
-# ifdef __ASSEMBLY__
-# define LANGUAGE Assembly
-# else
-# define LANGUAGE C
-# endif
-#endif
-
-/*
- * We have mapped the sa1101 depending on the value of SA1101_BASE.
- * It then appears from 0xf4000000.
- */
-
-#define SA1101_p2v( x ) ((x) - SA1101_BASE + 0xf4000000)
-#define SA1101_v2p( x ) ((x) - 0xf4000000 + SA1101_BASE)
-
-#ifndef SA1101_p2v
-#define SA1101_p2v(PhAdd) (PhAdd)
-#endif
-
-#include <mach/bitfield.h>
-
-#define C 0
-#define Assembly 1
-
-
-/*
- * Memory map
- */
-
-#define __SHMEM_CONTROL0 0x00000000
-#define __SYSTEM_CONTROL1 0x00000400
-#define __ARBITER 0x00020000
-#define __SYSTEM_CONTROL2 0x00040000
-#define __SYSTEM_CONTROL3 0x00060000
-#define __PARALLEL_PORT 0x00080000
-#define __VIDMEM_CONTROL 0x00100000
-#define __UPDATE_FIFO 0x00120000
-#define __SHMEM_CONTROL1 0x00140000
-#define __INTERRUPT_CONTROL 0x00160000
-#define __USB_CONTROL 0x00180000
-#define __TRACK_INTERFACE 0x001a0000
-#define __MOUSE_INTERFACE 0x001b0000
-#define __KEYPAD_INTERFACE 0x001c0000
-#define __PCMCIA_INTERFACE 0x001e0000
-#define __VGA_CONTROL 0x00200000
-#define __GPIO_INTERFACE 0x00300000
-
-/*
- * Macro that calculates real address for registers in the SA-1101
- */
-
-#define _SA1101( x ) ((x) + SA1101_BASE)
-
-/*
- * Interface and shared memory controller registers
- *
- * Registers
- * SKCR SA-1101 control register (read/write)
- * SMCR Shared Memory Controller Register
- * SNPR Snoop Register
- */
-
-#define _SKCR _SA1101( 0x00000000 ) /* SA-1101 Control Reg. */
-#define _SMCR _SA1101( 0x00140000 ) /* Shared Mem. Control Reg. */
-#define _SNPR _SA1101( 0x00140400 ) /* Snoop Reg. */
-
-#if LANGUAGE == C
-#define SKCR (*((volatile Word *) SA1101_p2v (_SKCR)))
-#define SMCR (*((volatile Word *) SA1101_p2v (_SMCR)))
-#define SNPR (*((volatile Word *) SA1101_p2v (_SNPR)))
-
-#define SKCR_PLLEn 0x0001 /* Enable On-Chip PLL */
-#define SKCR_BCLKEn 0x0002 /* Enables BCLK */
-#define SKCR_Sleep 0x0004 /* Sleep Mode */
-#define SKCR_IRefEn 0x0008 /* DAC Iref input enable */
-#define SKCR_VCOON 0x0010 /* VCO bias */
-#define SKCR_ScanTestEn 0x0020 /* Enables scan test */
-#define SKCR_ClockTestEn 0x0040 /* Enables clock test */
-
-#define SMCR_DCAC Fld(2,0) /* Number of column address bits */
-#define SMCR_DRAC Fld(2,2) /* Number of row address bits */
-#define SMCR_ArbiterBias 0x0008 /* favor video or USB */
-#define SMCR_TopVidMem Fld(4,5) /* Top 4 bits of vidmem addr. */
-
-#define SMCR_ColAdrBits( x ) /* col. addr bits 8..11 */ \
- (( (x) - 8 ) << FShft (SMCR_DCAC))
-#define SMCR_RowAdrBits( x ) /* row addr bits 9..12 */\
- (( (x) - 9 ) << FShft (SMCR_DRAC))
-
-#define SNPR_VFBstart Fld(12,0) /* Video frame buffer addr */
-#define SNPR_VFBsize Fld(11,12) /* Video frame buffer size */
-#define SNPR_WholeBank (1 << 23) /* Whole bank bit */
-#define SNPR_BankSelect Fld(2,27) /* Bank select */
-#define SNPR_SnoopEn (1 << 31) /* Enable snoop operation */
-
-#define SNPR_Set_VFBsize( x ) /* set frame buffer size (in kb) */ \
- ( (x) << FShft (SNPR_VFBsize))
-#define SNPR_Select_Bank(x) /* select bank 0 or 1 */ \
- (( (x) + 1 ) << FShft (SNPR_BankSelect ))
-
-#endif /* LANGUAGE == C */
-
-/*
- * Video Memory Controller
- *
- * Registers
- * VMCCR Configuration register
- * VMCAR VMC address register
- * VMCDR VMC data register
- *
- */
-
-#define _VMCCR _SA1101( 0x00100000 ) /* Configuration register */
-#define _VMCAR _SA1101( 0x00101000 ) /* VMC address register */
-#define _VMCDR _SA1101( 0x00101400 ) /* VMC data register */
-
-#if LANGUAGE == C
-#define VMCCR (*((volatile Word *) SA1101_p2v (_VMCCR)))
-#define VMCAR (*((volatile Word *) SA1101_p2v (_VMCAR)))
-#define VMCDR (*((volatile Word *) SA1101_p2v (_VMCDR)))
-
-#define VMCCR_RefreshEn 0x0000 /* Enable memory refresh */
-#define VMCCR_Config 0x0001 /* DRAM size */
-#define VMCCR_RefPeriod Fld(2,3) /* Refresh period */
-#define VMCCR_StaleDataWait Fld(4,5) /* Stale FIFO data timeout counter */
-#define VMCCR_SleepState (1<<9) /* State of interface pins in sleep*/
-#define VMCCR_RefTest (1<<10) /* refresh test */
-#define VMCCR_RefLow Fld(6,11) /* refresh low counter */
-#define VMCCR_RefHigh Fld(7,17) /* refresh high counter */
-#define VMCCR_SDTCTest Fld(7,24) /* stale data timeout counter */
-#define VMCCR_ForceSelfRef (1<<31) /* Force self refresh */
-
-#endif LANGUAGE == C
-
-
-/* Update FIFO
- *
- * Registers
- * UFCR Update FIFO Control Register
- * UFSR Update FIFO Status Register
- * UFLVLR update FIFO level register
- * UFDR update FIFO data register
- */
-
-#define _UFCR _SA1101(0x00120000) /* Update FIFO Control Reg. */
-#define _UFSR _SA1101(0x00120400) /* Update FIFO Status Reg. */
-#define _UFLVLR _SA1101(0x00120800) /* Update FIFO level reg. */
-#define _UFDR _SA1101(0x00120c00) /* Update FIFO data reg. */
-
-#if LANGUAGE == C
-
-#define UFCR (*((volatile Word *) SA1101_p2v (_UFCR)))
-#define UFSR (*((volatile Word *) SA1101_p2v (_UFSR)))
-#define UFLVLR (*((volatile Word *) SA1101_p2v (_UFLVLR)))
-#define UFDR (*((volatile Word *) SA1101_p2v (_UFDR)))
-
-
-#define UFCR_FifoThreshhold Fld(7,0) /* Level for FifoGTn flag */
-
-#define UFSR_FifoGTnFlag 0x01 /* FifoGTn flag */#define UFSR_FifoEmpty 0x80 /* FIFO is empty */
-
-#endif /* LANGUAGE == C */
-
-/* System Controller
- *
- * Registers
- * SKPCR Power Control Register
- * SKCDR Clock Divider Register
- * DACDR1 DAC1 Data register
- * DACDR2 DAC2 Data register
- */
-
-#define _SKPCR _SA1101(0x00000400)
-#define _SKCDR _SA1101(0x00040000)
-#define _DACDR1 _SA1101(0x00060000)
-#define _DACDR2 _SA1101(0x00060400)
-
-#if LANGUAGE == C
-#define SKPCR (*((volatile Word *) SA1101_p2v (_SKPCR)))
-#define SKCDR (*((volatile Word *) SA1101_p2v (_SKCDR)))
-#define DACDR1 (*((volatile Word *) SA1101_p2v (_DACDR1)))
-#define DACDR2 (*((volatile Word *) SA1101_p2v (_DACDR2)))
-
-#define SKPCR_UCLKEn 0x01 /* USB Enable */
-#define SKPCR_PCLKEn 0x02 /* PS/2 Enable */
-#define SKPCR_ICLKEn 0x04 /* Interrupt Controller Enable */
-#define SKPCR_VCLKEn 0x08 /* Video Controller Enable */
-#define SKPCR_PICLKEn 0x10 /* parallel port Enable */
-#define SKPCR_DCLKEn 0x20 /* DACs Enable */
-#define SKPCR_nKPADEn 0x40 /* Multiplexer */
-
-#define SKCDR_PLLMul Fld(7,0) /* PLL Multiplier */
-#define SKCDR_VCLKEn Fld(2,7) /* Video controller clock divider */
-#define SKDCR_BCLKEn (1<<9) /* BCLK Divider */
-#define SKDCR_UTESTCLKEn (1<<10) /* Route USB clock during test mode */
-#define SKDCR_DivRValue Fld(6,11) /* Input clock divider for PLL */
-#define SKDCR_DivNValue Fld(5,17) /* Output clock divider for PLL */
-#define SKDCR_PLLRSH Fld(3,22) /* PLL bandwidth control */
-#define SKDCR_ChargePump (1<<25) /* Charge pump control */
-#define SKDCR_ClkTestMode (1<<26) /* Clock output test mode */
-#define SKDCR_ClkTestEn (1<<27) /* Test clock generator */
-#define SKDCR_ClkJitterCntl Fld(3,28) /* video clock jitter compensation */
-
-#define DACDR_DACCount Fld(8,0) /* Count value */
-#define DACDR1_DACCount DACDR_DACCount
-#define DACDR2_DACCount DACDR_DACCount
-
-#endif /* LANGUAGE == C */
-
-/*
- * Parallel Port Interface
- *
- * Registers
- * IEEE_Config IEEE mode selection and programmable attributes
- * IEEE_Control Controls the states of IEEE port control outputs
- * IEEE_Data Forward transfer data register
- * IEEE_Addr Forward transfer address register
- * IEEE_Status Port IO signal status register
- * IEEE_IntStatus Port interrupts status register
- * IEEE_FifoLevels Rx and Tx FIFO interrupt generation levels
- * IEEE_InitTime Forward timeout counter initial value
- * IEEE_TimerStatus Forward timeout counter current value
- * IEEE_FifoReset Reset forward transfer FIFO
- * IEEE_ReloadValue Counter reload value
- * IEEE_TestControl Control testmode
- * IEEE_TestDataIn Test data register
- * IEEE_TestDataInEn Enable test data
- * IEEE_TestCtrlIn Test control signals
- * IEEE_TestCtrlInEn Enable test control signals
- * IEEE_TestDataStat Current data bus value
- *
- */
-
-/*
- * The control registers are defined as offsets from a base address
- */
-
-#define _IEEE( x ) _SA1101( (x) + __PARALLEL_PORT )
-
-#define _IEEE_Config _IEEE( 0x0000 )
-#define _IEEE_Control _IEEE( 0x0400 )
-#define _IEEE_Data _IEEE( 0x4000 )
-#define _IEEE_Addr _IEEE( 0x0800 )
-#define _IEEE_Status _IEEE( 0x0c00 )
-#define _IEEE_IntStatus _IEEE( 0x1000 )
-#define _IEEE_FifoLevels _IEEE( 0x1400 )
-#define _IEEE_InitTime _IEEE( 0x1800 )
-#define _IEEE_TimerStatus _IEEE( 0x1c00 )
-#define _IEEE_FifoReset _IEEE( 0x2000 )
-#define _IEEE_ReloadValue _IEEE( 0x3c00 )
-#define _IEEE_TestControl _IEEE( 0x2400 )
-#define _IEEE_TestDataIn _IEEE( 0x2800 )
-#define _IEEE_TestDataInEn _IEEE( 0x2c00 )
-#define _IEEE_TestCtrlIn _IEEE( 0x3000 )
-#define _IEEE_TestCtrlInEn _IEEE( 0x3400 )
-#define _IEEE_TestDataStat _IEEE( 0x3800 )
-
-
-#if LANGUAGE == C
-#define IEEE_Config (*((volatile Word *) SA1101_p2v (_IEEE_Config)))
-#define IEEE_Control (*((volatile Word *) SA1101_p2v (_IEEE_Control)))
-#define IEEE_Data (*((volatile Word *) SA1101_p2v (_IEEE_Data)))
-#define IEEE_Addr (*((volatile Word *) SA1101_p2v (_IEEE_Addr)))
-#define IEEE_Status (*((volatile Word *) SA1101_p2v (_IEEE_Status)))
-#define IEEE_IntStatus (*((volatile Word *) SA1101_p2v (_IEEE_IntStatus)))
-#define IEEE_FifoLevels (*((volatile Word *) SA1101_p2v (_IEEE_FifoLevels)))
-#define IEEE_InitTime (*((volatile Word *) SA1101_p2v (_IEEE_InitTime)))
-#define IEEE_TimerStatus (*((volatile Word *) SA1101_p2v (_IEEE_TimerStatus)))
-#define IEEE_FifoReset (*((volatile Word *) SA1101_p2v (_IEEE_FifoReset)))
-#define IEEE_ReloadValue (*((volatile Word *) SA1101_p2v (_IEEE_ReloadValue)))
-#define IEEE_TestControl (*((volatile Word *) SA1101_p2v (_IEEE_TestControl)))
-#define IEEE_TestDataIn (*((volatile Word *) SA1101_p2v (_IEEE_TestDataIn)))
-#define IEEE_TestDataInEn (*((volatile Word *) SA1101_p2v (_IEEE_TestDataInEn)))
-#define IEEE_TestCtrlIn (*((volatile Word *) SA1101_p2v (_IEEE_TestCtrlIn)))
-#define IEEE_TestCtrlInEn (*((volatile Word *) SA1101_p2v (_IEEE_TestCtrlInEn)))
-#define IEEE_TestDataStat (*((volatile Word *) SA1101_p2v (_IEEE_TestDataStat)))
-
-
-#define IEEE_Config_M Fld(3,0) /* Mode select */
-#define IEEE_Config_D 0x04 /* FIFO access enable */
-#define IEEE_Config_B 0x08 /* 9-bit word enable */
-#define IEEE_Config_T 0x10 /* Data transfer enable */
-#define IEEE_Config_A 0x20 /* Data transfer direction */
-#define IEEE_Config_E 0x40 /* Timer enable */
-#define IEEE_Control_A 0x08 /* AutoFd output */
-#define IEEE_Control_E 0x04 /* Selectin output */
-#define IEEE_Control_T 0x02 /* Strobe output */
-#define IEEE_Control_I 0x01 /* Port init output */
-#define IEEE_Data_C (1<<31) /* Byte count */
-#define IEEE_Data_Db Fld(9,16) /* Data byte 2 */
-#define IEEE_Data_Da Fld(9,0) /* Data byte 1 */
-#define IEEE_Addr_A Fld(8,0) /* forward address transfer byte */
-#define IEEE_Status_A 0x0100 /* nAutoFd port output status */
-#define IEEE_Status_E 0x0080 /* nSelectIn port output status */
-#define IEEE_Status_T 0x0040 /* nStrobe port output status */
-#define IEEE_Status_I 0x0020 /* nInit port output status */
-#define IEEE_Status_B 0x0010 /* Busy port inout status */
-#define IEEE_Status_S 0x0008 /* Select port input status */
-#define IEEE_Status_K 0x0004 /* nAck port input status */
-#define IEEE_Status_F 0x0002 /* nFault port input status */
-#define IEEE_Status_R 0x0001 /* pError port input status */
-
-#define IEEE_IntStatus_IntReqDat 0x0100
-#define IEEE_IntStatus_IntReqEmp 0x0080
-#define IEEE_IntStatus_IntReqInt 0x0040
-#define IEEE_IntStatus_IntReqRav 0x0020
-#define IEEE_IntStatus_IntReqTim 0x0010
-#define IEEE_IntStatus_RevAddrComp 0x0008
-#define IEEE_IntStatus_RevDataComp 0x0004
-#define IEEE_IntStatus_FwdAddrComp 0x0002
-#define IEEE_IntStatus_FwdDataComp 0x0001
-#define IEEE_FifoLevels_RevFifoLevel 2
-#define IEEE_FifoLevels_FwdFifoLevel 1
-#define IEEE_InitTime_TimValInit Fld(22,0)
-#define IEEE_TimerStatus_TimValStat Fld(22,0)
-#define IEEE_ReloadValue_Reload Fld(4,0)
-
-#define IEEE_TestControl_RegClk 0x04
-#define IEEE_TestControl_ClockSelect Fld(2,1)
-#define IEEE_TestControl_TimerTestModeEn 0x01
-#define IEEE_TestCtrlIn_PError 0x10
-#define IEEE_TestCtrlIn_nFault 0x08
-#define IEEE_TestCtrlIn_nAck 0x04
-#define IEEE_TestCtrlIn_PSel 0x02
-#define IEEE_TestCtrlIn_Busy 0x01
-
-#endif /* LANGUAGE == C */
-
-/*
- * VGA Controller
- *
- * Registers
- * VideoControl Video Control Register
- * VgaTiming0 VGA Timing Register 0
- * VgaTiming1 VGA Timing Register 1
- * VgaTiming2 VGA Timing Register 2
- * VgaTiming3 VGA Timing Register 3
- * VgaBorder VGA Border Color Register
- * VgaDBAR VGADMA Base Address Register
- * VgaDCAR VGADMA Channel Current Address Register
- * VgaStatus VGA Status Register
- * VgaInterruptMask VGA Interrupt Mask Register
- * VgaPalette VGA Palette Registers
- * DacControl DAC Control Register
- * VgaTest VGA Controller Test Register
- */
-
-#define _VGA( x ) _SA1101( ( x ) + __VGA_CONTROL )
-
-#define _VideoControl _VGA( 0x0000 )
-#define _VgaTiming0 _VGA( 0x0400 )
-#define _VgaTiming1 _VGA( 0x0800 )
-#define _VgaTiming2 _VGA( 0x0c00 )
-#define _VgaTiming3 _VGA( 0x1000 )
-#define _VgaBorder _VGA( 0x1400 )
-#define _VgaDBAR _VGA( 0x1800 )
-#define _VgaDCAR _VGA( 0x1c00 )
-#define _VgaStatus _VGA( 0x2000 )
-#define _VgaInterruptMask _VGA( 0x2400 )
-#define _VgaPalette _VGA( 0x40000 )
-#define _DacControl _VGA( 0x3000 )
-#define _VgaTest _VGA( 0x2c00 )
-
-#if (LANGUAGE == C)
-#define VideoControl (*((volatile Word *) SA1101_p2v (_VideoControl)))
-#define VgaTiming0 (*((volatile Word *) SA1101_p2v (_VgaTiming0)))
-#define VgaTiming1 (*((volatile Word *) SA1101_p2v (_VgaTiming1)))
-#define VgaTiming2 (*((volatile Word *) SA1101_p2v (_VgaTiming2)))
-#define VgaTiming3 (*((volatile Word *) SA1101_p2v (_VgaTiming3)))
-#define VgaBorder (*((volatile Word *) SA1101_p2v (_VgaBorder)))
-#define VgaDBAR (*((volatile Word *) SA1101_p2v (_VgaDBAR)))
-#define VgaDCAR (*((volatile Word *) SA1101_p2v (_VgaDCAR)))
-#define VgaStatus (*((volatile Word *) SA1101_p2v (_VgaStatus)))
-#define VgaInterruptMask (*((volatile Word *) SA1101_p2v (_VgaInterruptMask)))
-#define VgaPalette (*((volatile Word *) SA1101_p2v (_VgaPalette)))
-#define DacControl (*((volatile Word *) SA1101_p2v (_DacControl)))
-#define VgaTest (*((volatile Word *) SA1101_p2v (_VgaTest)))
-
-#define VideoControl_VgaEn 0x00000000
-#define VideoControl_BGR 0x00000001
-#define VideoControl_VCompVal Fld(2,2)
-#define VideoControl_VgaReq Fld(4,4)
-#define VideoControl_VBurstL Fld(4,8)
-#define VideoControl_VMode (1<<12)
-#define VideoControl_PalRead (1<<13)
-
-#define VgaTiming0_PPL Fld(6,2)
-#define VgaTiming0_HSW Fld(8,8)
-#define VgaTiming0_HFP Fld(8,16)
-#define VgaTiming0_HBP Fld(8,24)
-
-#define VgaTiming1_LPS Fld(10,0)
-#define VgaTiming1_VSW Fld(6,10)
-#define VgaTiming1_VFP Fld(8,16)
-#define VgaTiming1_VBP Fld(8,24)
-
-#define VgaTiming2_IVS 0x01
-#define VgaTiming2_IHS 0x02
-#define VgaTiming2_CVS 0x04
-#define VgaTiming2_CHS 0x08
-
-#define VgaTiming3_HBS Fld(8,0)
-#define VgaTiming3_HBE Fld(8,8)
-#define VgaTiming3_VBS Fld(8,16)
-#define VgaTiming3_VBE Fld(8,24)
-
-#define VgaBorder_BCOL Fld(24,0)
-
-#define VgaStatus_VFUF 0x01
-#define VgaStatus_VNext 0x02
-#define VgaStatus_VComp 0x04
-
-#define VgaInterruptMask_VFUFMask 0x00
-#define VgaInterruptMask_VNextMask 0x01
-#define VgaInterruptMask_VCompMask 0x02
-
-#define VgaPalette_R Fld(8,0)
-#define VgaPalette_G Fld(8,8)
-#define VgaPalette_B Fld(8,16)
-
-#define DacControl_DACON 0x0001
-#define DacControl_COMPON 0x0002
-#define DacControl_PEDON 0x0004
-#define DacControl_RTrim Fld(5,4)
-#define DacControl_GTrim Fld(5,9)
-#define DacControl_BTrim Fld(5,14)
-
-#define VgaTest_TDAC 0x00
-#define VgaTest_Datatest Fld(4,1)
-#define VgaTest_DACTESTDAC 0x10
-#define VgaTest_DACTESTOUT Fld(3,5)
-
-#endif /* LANGUAGE == C */
-
-/*
- * USB Host Interface Controller
- *
- * Registers
- * Revision
- * Control
- * CommandStatus
- * InterruptStatus
- * InterruptEnable
- * HCCA
- * PeriodCurrentED
- * ControlHeadED
- * BulkHeadED
- * BulkCurrentED
- * DoneHead
- * FmInterval
- * FmRemaining
- * FmNumber
- * PeriodicStart
- * LSThreshold
- * RhDescriptorA
- * RhDescriptorB
- * RhStatus
- * RhPortStatus
- * USBStatus
- * USBReset
- * USTAR
- * USWER
- * USRFR
- * USNFR
- * USTCSR
- * USSR
- *
- */
-
-#define _USB( x ) _SA1101( ( x ) + __USB_CONTROL )
-
-
-#define _Revision _USB( 0x0000 )
-#define _Control _USB( 0x0888 )
-#define _CommandStatus _USB( 0x0c00 )
-#define _InterruptStatus _USB( 0x1000 )
-#define _InterruptEnable _USB( 0x1400 )
-#define _HCCA _USB( 0x1800 )
-#define _PeriodCurrentED _USB( 0x1c00 )
-#define _ControlHeadED _USB( 0x2000 )
-#define _BulkHeadED _USB( 0x2800 )
-#define _BulkCurrentED _USB( 0x2c00 )
-#define _DoneHead _USB( 0x3000 )
-#define _FmInterval _USB( 0x3400 )
-#define _FmRemaining _USB( 0x3800 )
-#define _FmNumber _USB( 0x3c00 )
-#define _PeriodicStart _USB( 0x4000 )
-#define _LSThreshold _USB( 0x4400 )
-#define _RhDescriptorA _USB( 0x4800 )
-#define _RhDescriptorB _USB( 0x4c00 )
-#define _RhStatus _USB( 0x5000 )
-#define _RhPortStatus _USB( 0x5400 )
-#define _USBStatus _USB( 0x11800 )
-#define _USBReset _USB( 0x11c00 )
-
-#define _USTAR _USB( 0x10400 )
-#define _USWER _USB( 0x10800 )
-#define _USRFR _USB( 0x10c00 )
-#define _USNFR _USB( 0x11000 )
-#define _USTCSR _USB( 0x11400 )
-#define _USSR _USB( 0x11800 )
-
-
-#if (LANGUAGE == C)
-
-#define Revision (*((volatile Word *) SA1101_p2v (_Revision)))
-#define Control (*((volatile Word *) SA1101_p2v (_Control)))
-#define CommandStatus (*((volatile Word *) SA1101_p2v (_CommandStatus)))
-#define InterruptStatus (*((volatile Word *) SA1101_p2v (_InterruptStatus)))
-#define InterruptEnable (*((volatile Word *) SA1101_p2v (_InterruptEnable)))
-#define HCCA (*((volatile Word *) SA1101_p2v (_HCCA)))
-#define PeriodCurrentED (*((volatile Word *) SA1101_p2v (_PeriodCurrentED)))
-#define ControlHeadED (*((volatile Word *) SA1101_p2v (_ControlHeadED)))
-#define BulkHeadED (*((volatile Word *) SA1101_p2v (_BulkHeadED)))
-#define BulkCurrentED (*((volatile Word *) SA1101_p2v (_BulkCurrentED)))
-#define DoneHead (*((volatile Word *) SA1101_p2v (_DoneHead)))
-#define FmInterval (*((volatile Word *) SA1101_p2v (_FmInterval)))
-#define FmRemaining (*((volatile Word *) SA1101_p2v (_FmRemaining)))
-#define FmNumber (*((volatile Word *) SA1101_p2v (_FmNumber)))
-#define PeriodicStart (*((volatile Word *) SA1101_p2v (_PeriodicStart)))
-#define LSThreshold (*((volatile Word *) SA1101_p2v (_LSThreshold)))
-#define RhDescriptorA (*((volatile Word *) SA1101_p2v (_RhDescriptorA)))
-#define RhDescriptorB (*((volatile Word *) SA1101_p2v (_RhDescriptorB)))
-#define RhStatus (*((volatile Word *) SA1101_p2v (_RhStatus)))
-#define RhPortStatus (*((volatile Word *) SA1101_p2v (_RhPortStatus)))
-#define USBStatus (*((volatile Word *) SA1101_p2v (_USBStatus)))
-#define USBReset (*((volatile Word *) SA1101_p2v (_USBReset)))
-#define USTAR (*((volatile Word *) SA1101_p2v (_USTAR)))
-#define USWER (*((volatile Word *) SA1101_p2v (_USWER)))
-#define USRFR (*((volatile Word *) SA1101_p2v (_USRFR)))
-#define USNFR (*((volatile Word *) SA1101_p2v (_USNFR)))
-#define USTCSR (*((volatile Word *) SA1101_p2v (_USTCSR)))
-#define USSR (*((volatile Word *) SA1101_p2v (_USSR)))
-
-
-#define USBStatus_IrqHciRmtWkp (1<<7)
-#define USBStatus_IrqHciBuffAcc (1<<8)
-#define USBStatus_nIrqHciM (1<<9)
-#define USBStatus_nHciMFClr (1<<10)
-
-#define USBReset_ForceIfReset 0x01
-#define USBReset_ForceHcReset 0x02
-#define USBReset_ClkGenReset 0x04
-
-#define USTCR_RdBstCntrl Fld(3,0)
-#define USTCR_ByteEnable Fld(4,3)
-#define USTCR_WriteEn (1<<7)
-#define USTCR_FifoCir (1<<8)
-#define USTCR_TestXferSel (1<<9)
-#define USTCR_FifoCirAtEnd (1<<10)
-#define USTCR_nSimScaleDownClk (1<<11)
-
-#define USSR_nAppMDEmpty 0x01
-#define USSR_nAppMDFirst 0x02
-#define USSR_nAppMDLast 0x04
-#define USSR_nAppMDFull 0x08
-#define USSR_nAppMAFull 0x10
-#define USSR_XferReq 0x20
-#define USSR_XferEnd 0x40
-
-#endif /* LANGUAGE == C */
-
-
-/*
- * Interrupt Controller
- *
- * Registers
- * INTTEST0 Test register 0
- * INTTEST1 Test register 1
- * INTENABLE0 Interrupt Enable register 0
- * INTENABLE1 Interrupt Enable register 1
- * INTPOL0 Interrupt Polarity selection 0
- * INTPOL1 Interrupt Polarity selection 1
- * INTTSTSEL Interrupt source selection
- * INTSTATCLR0 Interrupt Status 0
- * INTSTATCLR1 Interrupt Status 1
- * INTSET0 Interrupt Set 0
- * INTSET1 Interrupt Set 1
- */
-
-#define _INT( x ) _SA1101( ( x ) + __INTERRUPT_CONTROL)
-
-#define _INTTEST0 _INT( 0x1000 )
-#define _INTTEST1 _INT( 0x1400 )
-#define _INTENABLE0 _INT( 0x2000 )
-#define _INTENABLE1 _INT( 0x2400 )
-#define _INTPOL0 _INT( 0x3000 )
-#define _INTPOL1 _INT( 0x3400 )
-#define _INTTSTSEL _INT( 0x5000 )
-#define _INTSTATCLR0 _INT( 0x6000 )
-#define _INTSTATCLR1 _INT( 0x6400 )
-#define _INTSET0 _INT( 0x7000 )
-#define _INTSET1 _INT( 0x7400 )
-
-#if ( LANGUAGE == C )
-#define INTTEST0 (*((volatile Word *) SA1101_p2v (_INTTEST0)))
-#define INTTEST1 (*((volatile Word *) SA1101_p2v (_INTTEST1)))
-#define INTENABLE0 (*((volatile Word *) SA1101_p2v (_INTENABLE0)))
-#define INTENABLE1 (*((volatile Word *) SA1101_p2v (_INTENABLE1)))
-#define INTPOL0 (*((volatile Word *) SA1101_p2v (_INTPOL0)))
-#define INTPOL1 (*((volatile Word *) SA1101_p2v (_INTPOL1)))
-#define INTTSTSEL (*((volatile Word *) SA1101_p2v (_INTTSTSEL)))
-#define INTSTATCLR0 (*((volatile Word *) SA1101_p2v (_INTSTATCLR0)))
-#define INTSTATCLR1 (*((volatile Word *) SA1101_p2v (_INTSTATCLR1)))
-#define INTSET0 (*((volatile Word *) SA1101_p2v (_INTSET0)))
-#define INTSET1 (*((volatile Word *) SA1101_p2v (_INTSET1)))
-
-#endif /* LANGUAGE == C */
-
-/*
- * PS/2 Trackpad and Mouse Interfaces
- *
- * Registers (prefix kbd applies to trackpad interface, mse to mouse)
- * KBDCR Control Register
- * KBDSTAT Status Register
- * KBDDATA Transmit/Receive Data register
- * KBDCLKDIV Clock Division Register
- * KBDPRECNT Clock Precount Register
- * KBDTEST1 Test register 1
- * KBDTEST2 Test register 2
- * KBDTEST3 Test register 3
- * KBDTEST4 Test register 4
- * MSECR
- * MSESTAT
- * MSEDATA
- * MSECLKDIV
- * MSEPRECNT
- * MSETEST1
- * MSETEST2
- * MSETEST3
- * MSETEST4
- *
- */
-
-#define _KBD( x ) _SA1101( ( x ) + __TRACK_INTERFACE )
-#define _MSE( x ) _SA1101( ( x ) + __MOUSE_INTERFACE )
-
-#define _KBDCR _KBD( 0x0000 )
-#define _KBDSTAT _KBD( 0x0400 )
-#define _KBDDATA _KBD( 0x0800 )
-#define _KBDCLKDIV _KBD( 0x0c00 )
-#define _KBDPRECNT _KBD( 0x1000 )
-#define _KBDTEST1 _KBD( 0x2000 )
-#define _KBDTEST2 _KBD( 0x2400 )
-#define _KBDTEST3 _KBD( 0x2800 )
-#define _KBDTEST4 _KBD( 0x2c00 )
-#define _MSECR _MSE( 0x0000 )
-#define _MSESTAT _MSE( 0x0400 )
-#define _MSEDATA _MSE( 0x0800 )
-#define _MSECLKDIV _MSE( 0x0c00 )
-#define _MSEPRECNT _MSE( 0x1000 )
-#define _MSETEST1 _MSE( 0x2000 )
-#define _MSETEST2 _MSE( 0x2400 )
-#define _MSETEST3 _MSE( 0x2800 )
-#define _MSETEST4 _MSE( 0x2c00 )
-
-#if ( LANGUAGE == C )
-
-#define KBDCR (*((volatile Word *) SA1101_p2v (_KBDCR)))
-#define KBDSTAT (*((volatile Word *) SA1101_p2v (_KBDSTAT)))
-#define KBDDATA (*((volatile Word *) SA1101_p2v (_KBDDATA)))
-#define KBDCLKDIV (*((volatile Word *) SA1101_p2v (_KBDCLKDIV)))
-#define KBDPRECNT (*((volatile Word *) SA1101_p2v (_KBDPRECNT)))
-#define KBDTEST1 (*((volatile Word *) SA1101_p2v (_KBDTEST1)))
-#define KBDTEST2 (*((volatile Word *) SA1101_p2v (_KBDTEST2)))
-#define KBDTEST3 (*((volatile Word *) SA1101_p2v (_KBDTEST3)))
-#define KBDTEST4 (*((volatile Word *) SA1101_p2v (_KBDTEST4)))
-#define MSECR (*((volatile Word *) SA1101_p2v (_MSECR)))
-#define MSESTAT (*((volatile Word *) SA1101_p2v (_MSESTAT)))
-#define MSEDATA (*((volatile Word *) SA1101_p2v (_MSEDATA)))
-#define MSECLKDIV (*((volatile Word *) SA1101_p2v (_MSECLKDIV)))
-#define MSEPRECNT (*((volatile Word *) SA1101_p2v (_MSEPRECNT)))
-#define MSETEST1 (*((volatile Word *) SA1101_p2v (_MSETEST1)))
-#define MSETEST2 (*((volatile Word *) SA1101_p2v (_MSETEST2)))
-#define MSETEST3 (*((volatile Word *) SA1101_p2v (_MSETEST3)))
-#define MSETEST4 (*((volatile Word *) SA1101_p2v (_MSETEST4)))
-
-
-#define KBDCR_ENA 0x08
-#define KBDCR_FKD 0x02
-#define KBDCR_FKC 0x01
-
-#define KBDSTAT_TXE 0x80
-#define KBDSTAT_TXB 0x40
-#define KBDSTAT_RXF 0x20
-#define KBDSTAT_RXB 0x10
-#define KBDSTAT_ENA 0x08
-#define KBDSTAT_RXP 0x04
-#define KBDSTAT_KBD 0x02
-#define KBDSTAT_KBC 0x01
-
-#define KBDCLKDIV_DivVal Fld(4,0)
-
-#define MSECR_ENA 0x08
-#define MSECR_FKD 0x02
-#define MSECR_FKC 0x01
-
-#define MSESTAT_TXE 0x80
-#define MSESTAT_TXB 0x40
-#define MSESTAT_RXF 0x20
-#define MSESTAT_RXB 0x10
-#define MSESTAT_ENA 0x08
-#define MSESTAT_RXP 0x04
-#define MSESTAT_MSD 0x02
-#define MSESTAT_MSC 0x01
-
-#define MSECLKDIV_DivVal Fld(4,0)
-
-#define KBDTEST1_CD 0x80
-#define KBDTEST1_RC1 0x40
-#define KBDTEST1_MC 0x20
-#define KBDTEST1_C Fld(2,3)
-#define KBDTEST1_T2 0x40
-#define KBDTEST1_T1 0x20
-#define KBDTEST1_T0 0x10
-#define KBDTEST2_TICBnRES 0x08
-#define KBDTEST2_RKC 0x04
-#define KBDTEST2_RKD 0x02
-#define KBDTEST2_SEL 0x01
-#define KBDTEST3_ms_16 0x80
-#define KBDTEST3_us_64 0x40
-#define KBDTEST3_us_16 0x20
-#define KBDTEST3_DIV8 0x10
-#define KBDTEST3_DIn 0x08
-#define KBDTEST3_CIn 0x04
-#define KBDTEST3_KD 0x02
-#define KBDTEST3_KC 0x01
-#define KBDTEST4_BC12 0x80
-#define KBDTEST4_BC11 0x40
-#define KBDTEST4_TRES 0x20
-#define KBDTEST4_CLKOE 0x10
-#define KBDTEST4_CRES 0x08
-#define KBDTEST4_RXB 0x04
-#define KBDTEST4_TXB 0x02
-#define KBDTEST4_SRX 0x01
-
-#define MSETEST1_CD 0x80
-#define MSETEST1_RC1 0x40
-#define MSETEST1_MC 0x20
-#define MSETEST1_C Fld(2,3)
-#define MSETEST1_T2 0x40
-#define MSETEST1_T1 0x20
-#define MSETEST1_T0 0x10
-#define MSETEST2_TICBnRES 0x08
-#define MSETEST2_RKC 0x04
-#define MSETEST2_RKD 0x02
-#define MSETEST2_SEL 0x01
-#define MSETEST3_ms_16 0x80
-#define MSETEST3_us_64 0x40
-#define MSETEST3_us_16 0x20
-#define MSETEST3_DIV8 0x10
-#define MSETEST3_DIn 0x08
-#define MSETEST3_CIn 0x04
-#define MSETEST3_KD 0x02
-#define MSETEST3_KC 0x01
-#define MSETEST4_BC12 0x80
-#define MSETEST4_BC11 0x40
-#define MSETEST4_TRES 0x20
-#define MSETEST4_CLKOE 0x10
-#define MSETEST4_CRES 0x08
-#define MSETEST4_RXB 0x04
-#define MSETEST4_TXB 0x02
-#define MSETEST4_SRX 0x01
-
-#endif /* LANGUAGE == C */
-
-
-/*
- * General-Purpose I/O Interface
- *
- * Registers
- * PADWR Port A Data Write Register
- * PBDWR Port B Data Write Register
- * PADRR Port A Data Read Register
- * PBDRR Port B Data Read Register
- * PADDR Port A Data Direction Register
- * PBDDR Port B Data Direction Register
- * PASSR Port A Sleep State Register
- * PBSSR Port B Sleep State Register
- *
- */
-
-#define _PIO( x ) _SA1101( ( x ) + __GPIO_INTERFACE )
-
-#define _PADWR _PIO( 0x0000 )
-#define _PBDWR _PIO( 0x0400 )
-#define _PADRR _PIO( 0x0000 )
-#define _PBDRR _PIO( 0x0400 )
-#define _PADDR _PIO( 0x0800 )
-#define _PBDDR _PIO( 0x0c00 )
-#define _PASSR _PIO( 0x1000 )
-#define _PBSSR _PIO( 0x1400 )
-
-
-#if ( LANGUAGE == C )
-
-
-#define PADWR (*((volatile Word *) SA1101_p2v (_PADWR)))
-#define PBDWR (*((volatile Word *) SA1101_p2v (_PBDWR)))
-#define PADRR (*((volatile Word *) SA1101_p2v (_PADRR)))
-#define PBDRR (*((volatile Word *) SA1101_p2v (_PBDRR)))
-#define PADDR (*((volatile Word *) SA1101_p2v (_PADDR)))
-#define PBDDR (*((volatile Word *) SA1101_p2v (_PBDDR)))
-#define PASSR (*((volatile Word *) SA1101_p2v (_PASSR)))
-#define PBSSR (*((volatile Word *) SA1101_p2v (_PBSSR)))
-
-#endif
-
-
-
-/*
- * Keypad Interface
- *
- * Registers
- * PXDWR
- * PXDRR
- * PYDWR
- * PYDRR
- *
- */
-
-#define _KEYPAD( x ) _SA1101( ( x ) + __KEYPAD_INTERFACE )
-
-#define _PXDWR _KEYPAD( 0x0000 )
-#define _PXDRR _KEYPAD( 0x0000 )
-#define _PYDWR _KEYPAD( 0x0400 )
-#define _PYDRR _KEYPAD( 0x0400 )
-
-#if ( LANGUAGE == C )
-
-
-#define PXDWR (*((volatile Word *) SA1101_p2v (_PXDWR)))
-#define PXDRR (*((volatile Word *) SA1101_p2v (_PXDRR)))
-#define PYDWR (*((volatile Word *) SA1101_p2v (_PYDWR)))
-#define PYDRR (*((volatile Word *) SA1101_p2v (_PYDRR)))
-
-#endif
-
-
-
-/*
- * PCMCIA Interface
- *
- * Registers
- * PCSR Status Register
- * PCCR Control Register
- * PCSSR Sleep State Register
- *
- */
-
-#define _CARD( x ) _SA1101( ( x ) + __PCMCIA_INTERFACE )
-
-#define _PCSR _CARD( 0x0000 )
-#define _PCCR _CARD( 0x0400 )
-#define _PCSSR _CARD( 0x0800 )
-
-#if ( LANGUAGE == C )
-#define PCSR (*((volatile Word *) SA1101_p2v (_PCSR)))
-#define PCCR (*((volatile Word *) SA1101_p2v (_PCCR)))
-#define PCSSR (*((volatile Word *) SA1101_p2v (_PCSSR)))
-
-#define PCSR_S0_ready 0x0001
-#define PCSR_S1_ready 0x0002
-#define PCSR_S0_detected 0x0004
-#define PCSR_S1_detected 0x0008
-#define PCSR_S0_VS1 0x0010
-#define PCSR_S0_VS2 0x0020
-#define PCSR_S1_VS1 0x0040
-#define PCSR_S1_VS2 0x0080
-#define PCSR_S0_WP 0x0100
-#define PCSR_S1_WP 0x0200
-#define PCSR_S0_BVD1_nSTSCHG 0x0400
-#define PCSR_S0_BVD2_nSPKR 0x0800
-#define PCSR_S1_BVD1_nSTSCHG 0x1000
-#define PCSR_S1_BVD2_nSPKR 0x2000
-
-#define PCCR_S0_VPP0 0x0001
-#define PCCR_S0_VPP1 0x0002
-#define PCCR_S0_VCC0 0x0004
-#define PCCR_S0_VCC1 0x0008
-#define PCCR_S1_VPP0 0x0010
-#define PCCR_S1_VPP1 0x0020
-#define PCCR_S1_VCC0 0x0040
-#define PCCR_S1_VCC1 0x0080
-#define PCCR_S0_reset 0x0100
-#define PCCR_S1_reset 0x0200
-#define PCCR_S0_float 0x0400
-#define PCCR_S1_float 0x0800
-
-#define PCSSR_S0_VCC0 0x0001
-#define PCSSR_S0_VCC1 0x0002
-#define PCSSR_S0_VPP0 0x0004
-#define PCSSR_S0_VPP1 0x0008
-#define PCSSR_S0_control 0x0010
-#define PCSSR_S1_VCC0 0x0020
-#define PCSSR_S1_VCC1 0x0040
-#define PCSSR_S1_VPP0 0x0080
-#define PCSSR_S1_VPP1 0x0100
-#define PCSSR_S1_control 0x0200
-
-#endif
-
-#undef C
-#undef Assembly
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index d944fd7e464f..cc43f95f33cc 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -43,10 +43,6 @@
# define __REG(x) (*((volatile unsigned long __iomem *)io_p2v(x)))
# define __PREG(x) (io_v2p((unsigned long)&(x)))
-static inline unsigned long get_clock_tick_rate(void)
-{
- return 3686400;
-}
#else
# define __REG(x) io_p2v(x)
@@ -56,8 +52,4 @@ static inline unsigned long get_clock_tick_rate(void)
#include "SA-1100.h"
-#ifdef CONFIG_SA1101
-#include "SA-1101.h"
-#endif
-
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 09817bae4558..2bb4b09f079e 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -32,15 +32,16 @@ config ARCH_RMOBILE
menuconfig ARCH_RENESAS
bool "Renesas ARM SoCs"
depends on ARCH_MULTI_V7 && MMU
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_SHMOBILE
select ARCH_SHMOBILE_MULTI
+ select ARM_GIC
+ select GPIOLIB
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
- select ARM_GIC
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select NO_IOPORT_MAP
select PINCTRL
- select GPIOLIB
+ select SOC_BUS
select ZONE_DMA if ARM_LPAE
if ARCH_RENESAS
@@ -60,6 +61,7 @@ config ARCH_R7S72100
config ARCH_R8A73A4
bool "R-Mobile APE6 (R8A73A40)"
select ARCH_RMOBILE
+ select ARM_ERRATA_798181 if SMP
select RENESAS_IRQC
config ARCH_R8A7740
@@ -67,6 +69,15 @@ config ARCH_R8A7740
select ARCH_RMOBILE
select RENESAS_INTC_IRQPIN
+config ARCH_R8A7743
+ bool "RZ/G1M (R8A77430)"
+ select ARCH_RCAR_GEN2
+ select ARM_ERRATA_798181 if SMP
+
+config ARCH_R8A7745
+ bool "RZ/G1E (R8A77450)"
+ select ARCH_RCAR_GEN2
+
config ARCH_R8A7778
bool "R-Car M1A (R8A77781)"
select ARCH_RCAR_GEN1
@@ -78,20 +89,24 @@ config ARCH_R8A7779
config ARCH_R8A7790
bool "R-Car H2 (R8A77900)"
select ARCH_RCAR_GEN2
+ select ARM_ERRATA_798181 if SMP
select I2C
config ARCH_R8A7791
bool "R-Car M2-W (R8A77910)"
select ARCH_RCAR_GEN2
+ select ARM_ERRATA_798181 if SMP
select I2C
config ARCH_R8A7792
bool "R-Car V2H (R8A77920)"
select ARCH_RCAR_GEN2
+ select ARM_ERRATA_798181 if SMP
config ARCH_R8A7793
bool "R-Car M2-N (R8A7793)"
select ARCH_RCAR_GEN2
+ select ARM_ERRATA_798181 if SMP
select I2C
config ARCH_R8A7794
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 3fc48b02eb4f..64611a1b4276 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -13,9 +13,6 @@ obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
-obj-$(CONFIG_ARCH_R8A7792) += setup-r8a7792.o
-obj-$(CONFIG_ARCH_R8A7793) += setup-r8a7793.o
-obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
diff --git a/arch/arm/mach-shmobile/setup-r8a7792.c b/arch/arm/mach-shmobile/setup-r8a7792.c
deleted file mode 100644
index a0910395da09..000000000000
--- a/arch/arm/mach-shmobile/setup-r8a7792.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * r8a7792 processor support
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- * Copyright (C) 2016 Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "rcar-gen2.h"
-
-static const char * const r8a7792_boards_compat_dt[] __initconst = {
- "renesas,r8a7792",
- NULL,
-};
-
-DT_MACHINE_START(R8A7792_DT, "Generic R8A7792 (Flattened Device Tree)")
- .init_early = shmobile_init_delay,
- .init_late = shmobile_init_late,
- .init_time = rcar_gen2_timer_init,
- .reserve = rcar_gen2_reserve,
- .dt_compat = r8a7792_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7793.c b/arch/arm/mach-shmobile/setup-r8a7793.c
deleted file mode 100644
index 5fce87f7f254..000000000000
--- a/arch/arm/mach-shmobile/setup-r8a7793.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * r8a7793 processor support
- *
- * Copyright (C) 2015 Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/init.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "rcar-gen2.h"
-
-static const char * const r8a7793_boards_compat_dt[] __initconst = {
- "renesas,r8a7793",
- NULL,
-};
-
-DT_MACHINE_START(R8A7793_DT, "Generic R8A7793 (Flattened Device Tree)")
- .init_early = shmobile_init_delay,
- .init_time = rcar_gen2_timer_init,
- .init_late = shmobile_init_late,
- .reserve = rcar_gen2_reserve,
- .dt_compat = r8a7793_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7794.c b/arch/arm/mach-shmobile/setup-r8a7794.c
deleted file mode 100644
index d2b093033132..000000000000
--- a/arch/arm/mach-shmobile/setup-r8a7794.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * r8a7794 processor support
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- * Copyright (C) 2014 Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/of_platform.h>
-#include "common.h"
-#include "rcar-gen2.h"
-#include <asm/mach/arch.h>
-
-static const char * const r8a7794_boards_compat_dt[] __initconst = {
- "renesas,r8a7794",
- NULL,
-};
-
-DT_MACHINE_START(R8A7794_DT, "Generic R8A7794 (Flattened Device Tree)")
- .init_early = shmobile_init_delay,
- .init_late = shmobile_init_late,
- .init_time = rcar_gen2_timer_init,
- .reserve = rcar_gen2_reserve,
- .dt_compat = r8a7794_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index b527258e0a62..ac63fa407b64 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -24,6 +24,7 @@
#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include "common.h"
#include "rcar-gen2.h"
@@ -202,3 +203,36 @@ void __init rcar_gen2_reserve(void)
}
#endif
}
+
+static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
+ /*
+ * R8A7790 and R8A7791 can't be handled here as long as they need SMP
+ * initialization fallback.
+ */
+ "renesas,r8a7792",
+ "renesas,r8a7793",
+ "renesas,r8a7794",
+ NULL,
+};
+
+DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
+ .init_early = shmobile_init_delay,
+ .init_late = shmobile_init_late,
+ .init_time = rcar_gen2_timer_init,
+ .reserve = rcar_gen2_reserve,
+ .dt_compat = rcar_gen2_boards_compat_dt,
+MACHINE_END
+
+static const char * const rz_g1_boards_compat_dt[] __initconst = {
+ "renesas,r8a7743",
+ "renesas,r8a7745",
+ NULL,
+};
+
+DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
+ .init_early = shmobile_init_delay,
+ .init_late = shmobile_init_late,
+ .init_time = rcar_gen2_timer_init,
+ .reserve = rcar_gen2_reserve,
+ .dt_compat = rz_g1_boards_compat_dt,
+MACHINE_END
diff --git a/arch/arm/mach-socfpga/l2_cache.c b/arch/arm/mach-socfpga/l2_cache.c
index 4267c95f2158..bb359d727b34 100644
--- a/arch/arm/mach-socfpga/l2_cache.c
+++ b/arch/arm/mach-socfpga/l2_cache.c
@@ -74,7 +74,7 @@ void socfpga_init_arria10_l2_ecc(void)
}
if (!sys_manager_base_addr) {
- pr_err("System Mananger not mapped for L2 ECC\n");
+ pr_err("System Manager not mapped for L2 ECC\n");
goto exit;
}
/* Clear any pending IRQs */
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
index 9ccffc1d0f28..4878ba90026d 100644
--- a/arch/arm/mach-spear/time.c
+++ b/arch/arm/mach-spear/time.c
@@ -233,7 +233,7 @@ void __init spear_setup_of_timer(void)
}
gpt_clk = clk_get_sys("gpt0", NULL);
- if (!gpt_clk) {
+ if (IS_ERR(gpt_clk)) {
pr_err("%s:couldn't get clk for gpt\n", __func__);
goto err_iomap;
}
diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig
index 119e1108b1f8..f8eeeffddaff 100644
--- a/arch/arm/mach-sti/Kconfig
+++ b/arch/arm/mach-sti/Kconfig
@@ -28,7 +28,6 @@ if ARCH_STI
config SOC_STIH415
bool "STiH415 STMicroelectronics Consumer Electronics family"
default y
- select STIH415_RESET
help
This enables support for STMicroelectronics Digital Consumer
Electronics family StiH415 parts, primarily targeted at set-top-box
@@ -38,7 +37,6 @@ config SOC_STIH415
config SOC_STIH416
bool "STiH416 STMicroelectronics Consumer Electronics family"
default y
- select STIH416_RESET
help
This enables support for STMicroelectronics Digital Consumer
Electronics family StiH416 parts, primarily targeted at set-top-box
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
index ceee47735eec..c354222a4158 100644
--- a/arch/arm/mach-stm32/board-dt.c
+++ b/arch/arm/mach-stm32/board-dt.c
@@ -11,6 +11,7 @@
static const char *const stm32_compat[] __initconst = {
"st,stm32f429",
"st,stm32f469",
+ "st,stm32f746",
NULL
};
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 8b8d0724f6c6..98e29dee91e8 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -26,19 +26,37 @@
bool __init vexpress_smp_init_ops(void)
{
#ifdef CONFIG_MCPM
+ int cpu;
+ struct device_node *cpu_node, *cci_node;
+
/*
- * The best way to detect a multi-cluster configuration at the moment
- * is to look for the presence of a CCI in the system.
+ * The best way to detect a multi-cluster configuration
+ * is to detect if the kernel can take over CCI ports
+ * control. Loop over possible CPUs and check if CCI
+ * port control is available.
* Override the default vexpress_smp_ops if so.
*/
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "arm,cci-400");
- if (node && of_device_is_available(node)) {
- mcpm_smp_set_ops();
- return true;
+ for_each_possible_cpu(cpu) {
+ bool available;
+
+ cpu_node = of_get_cpu_node(cpu, NULL);
+ if (WARN(!cpu_node, "Missing cpu device node!"))
+ return false;
+
+ cci_node = of_parse_phandle(cpu_node, "cci-control-port", 0);
+ available = cci_node && of_device_is_available(cci_node);
+ of_node_put(cci_node);
+ of_node_put(cpu_node);
+
+ if (!available)
+ return false;
}
-#endif
+
+ mcpm_smp_set_ops();
+ return true;
+#else
return false;
+#endif
}
static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {
diff --git a/arch/arm/mach-zx/zx296702-pm-domain.c b/arch/arm/mach-zx/zx296702-pm-domain.c
index e08574d4e2ca..79dcf2549267 100644
--- a/arch/arm/mach-zx/zx296702-pm-domain.c
+++ b/arch/arm/mach-zx/zx296702-pm-domain.c
@@ -169,7 +169,7 @@ static int zx296702_pd_probe(struct platform_device *pdev)
}
pcubase = devm_ioremap_resource(&pdev->dev, res);
- if (!pcubase) {
+ if (IS_ERR(pcubase)) {
dev_err(&pdev->dev, "ioremap fail.\n");
return -EIO;
}
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index d12002cd63bc..ed118648313f 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -59,7 +59,7 @@ void __iomem *zynq_scu_base;
static void __init zynq_memory_init(void)
{
if (!__pa(PAGE_OFFSET))
- memblock_reserve(__pa(PAGE_OFFSET), __pa(swapper_pg_dir));
+ memblock_reserve(__pa(PAGE_OFFSET), 0x80000);
}
static struct platform_device zynq_cpuidle_device = {
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c1799dd1d0d9..f68e8ec29447 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -991,7 +991,7 @@ config CACHE_TAUROS2
config CACHE_UNIPHIER
bool "Enable the UniPhier outer cache controller"
depends on ARCH_UNIPHIER
- default y
+ select ARM_L1_CACHE_SHIFT_7
select OUTER_CACHE
select OUTER_CACHE_SYNC
help
@@ -1012,8 +1012,14 @@ config ARM_L1_CACHE_SHIFT_6
help
Setting ARM L1 cache line size to 64 Bytes.
+config ARM_L1_CACHE_SHIFT_7
+ bool
+ help
+ Setting ARM L1 cache line size to 128 Bytes.
+
config ARM_L1_CACHE_SHIFT
int
+ default 7 if ARM_L1_CACHE_SHIFT_7
default 6 if ARM_L1_CACHE_SHIFT_6
default 5
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
index d19b1ad29b07..3b69f2642513 100644
--- a/arch/arm/mm/pageattr.c
+++ b/arch/arm/mm/pageattr.c
@@ -34,28 +34,29 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
return 0;
}
+static bool in_range(unsigned long start, unsigned long size,
+ unsigned long range_start, unsigned long range_end)
+{
+ return start >= range_start && start < range_end &&
+ size <= range_end - start;
+}
+
static int change_memory_common(unsigned long addr, int numpages,
pgprot_t set_mask, pgprot_t clear_mask)
{
- unsigned long start = addr;
- unsigned long size = PAGE_SIZE*numpages;
- unsigned long end = start + size;
+ unsigned long start = addr & PAGE_MASK;
+ unsigned long end = PAGE_ALIGN(addr) + numpages * PAGE_SIZE;
+ unsigned long size = end - start;
int ret;
struct page_change_data data;
- if (!IS_ALIGNED(addr, PAGE_SIZE)) {
- start &= PAGE_MASK;
- end = start + size;
- WARN_ON_ONCE(1);
- }
+ WARN_ON_ONCE(start != addr);
- if (!numpages)
+ if (!size)
return 0;
- if (start < MODULES_VADDR || start >= MODULES_END)
- return -EINVAL;
-
- if (end < MODULES_VADDR || start >= MODULES_END)
+ if (!in_range(start, size, MODULES_VADDR, MODULES_END) &&
+ !in_range(start, size, VMALLOC_START, VMALLOC_END))
return -EINVAL;
data.set_mask = set_mask;
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index d055db32ffcb..3e27bffb352d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -63,32 +63,6 @@ config OMAP_RESET_CLOCKS
probably do not want this option enabled until your
device drivers work properly.
-config OMAP_MUX
- bool "OMAP multiplexing support"
- depends on ARCH_OMAP
- default y
- help
- Pin multiplexing support for OMAP boards. If your bootloader
- sets the multiplexing correctly, say N. Otherwise, or if unsure,
- say Y.
-
-config OMAP_MUX_DEBUG
- bool "Multiplexing debug output"
- depends on OMAP_MUX
- help
- Makes the multiplexing functions print out a lot of debug info.
- This is useful if you want to find out the correct values of the
- multiplexing registers.
-
-config OMAP_MUX_WARNINGS
- bool "Warn about pins the bootloader didn't set up"
- depends on OMAP_MUX
- default y
- help
- Choose Y here to warn whenever driver initialization logic needs
- to change the pin multiplexing setup. When there are no warnings
- printed, it's safe to deselect OMAP_MUX for your product.
-
config OMAP_MPU_TIMER
bool "Use mpu timer"
depends on ARCH_OMAP1
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 97a50e8883f9..47e186729d44 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -11,6 +11,3 @@ obj-y := sram.o dma.o counter_32k.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
-i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
-obj-y += $(i2c-omap-m) $(i2c-omap-y)
-
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
deleted file mode 100644
index 58213d9714cd..000000000000
--- a/arch/arm/plat-omap/i2c.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/i2c.c
- *
- * Helper module for board specific I2C bus registration
- *
- * Copyright (C) 2007 Nokia Corporation.
- *
- * Contact: Jarkko Nikula <jhnikula@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.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/i2c-omap.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-
-#include <plat/i2c.h>
-
-#define OMAP_I2C_MAX_CONTROLLERS 4
-static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
-
-#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
-
-/**
- * omap_i2c_bus_setup - Process command line options for the I2C bus speed
- * @str: String of options
- *
- * This function allow to override the default I2C bus speed for given I2C
- * bus with a command line option.
- *
- * Format: i2c_bus=bus_id,clkrate (in kHz)
- *
- * Returns 1 on success, 0 otherwise.
- */
-static int __init omap_i2c_bus_setup(char *str)
-{
- int ints[3];
-
- get_options(str, 3, ints);
- if (ints[0] < 2 || ints[1] < 1 ||
- ints[1] > OMAP_I2C_MAX_CONTROLLERS)
- return 0;
- i2c_pdata[ints[1] - 1].clkrate = ints[2];
- i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP;
-
- return 1;
-}
-__setup("i2c_bus=", omap_i2c_bus_setup);
-
-/*
- * Register busses defined in command line but that are not registered with
- * omap_register_i2c_bus from board initialization code.
- */
-int __init omap_register_i2c_bus_cmdline(void)
-{
- int i, err = 0;
-
- for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++)
- if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) {
- i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
- err = omap_i2c_add_bus(&i2c_pdata[i], i + 1);
- if (err)
- goto out;
- }
-
-out:
- return err;
-}
-
-/**
- * omap_register_i2c_bus - register I2C bus with device descriptors
- * @bus_id: bus id counting from number 1
- * @clkrate: clock rate of the bus in kHz
- * @info: pointer into I2C device descriptor table or NULL
- * @len: number of descriptors in the table
- *
- * Returns 0 on success or an error code.
- */
-int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
- struct i2c_board_info const *info,
- unsigned len)
-{
- int err;
-
- BUG_ON(bus_id < 1 || bus_id > OMAP_I2C_MAX_CONTROLLERS);
-
- if (info) {
- err = i2c_register_board_info(bus_id, info, len);
- if (err)
- return err;
- }
-
- if (!i2c_pdata[bus_id - 1].clkrate)
- i2c_pdata[bus_id - 1].clkrate = clkrate;
-
- i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
-
- return omap_i2c_add_bus(&i2c_pdata[bus_id - 1], bus_id);
-}
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index f74069386c13..26a531ebb6e9 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -478,13 +478,13 @@ static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
(data_in ^ in_pol) & msk ? "hi" : "lo",
in_pol & msk ? "lo" : "hi");
if (!((edg_msk | lvl_msk) & msk)) {
- seq_printf(s, " disabled\n");
+ seq_puts(s, " disabled\n");
continue;
}
if (edg_msk & msk)
- seq_printf(s, " edge ");
+ seq_puts(s, " edge ");
if (lvl_msk & msk)
- seq_printf(s, " level");
+ seq_puts(s, " level");
seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear ");
}
}
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index e93aa6734147..cf7b95fddbb3 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1124,15 +1124,6 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
- pd.dma_tx = (void *)DMACH_SPI0_TX;
- pd.dma_rx = (void *)DMACH_SPI0_RX;
-#if defined(CONFIG_PL330_DMA)
- pd.filter = pl330_filter;
-#elif defined(CONFIG_S3C64XX_PL080)
- pd.filter = pl08x_filter_id;
-#elif defined(CONFIG_S3C24XX_DMAC)
- pd.filter = s3c24xx_dma_filter;
-#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
}
@@ -1169,14 +1160,6 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
- pd.dma_tx = (void *)DMACH_SPI1_TX;
- pd.dma_rx = (void *)DMACH_SPI1_RX;
-#if defined(CONFIG_PL330_DMA)
- pd.filter = pl330_filter;
-#elif defined(CONFIG_S3C64XX_PL080)
- pd.filter = pl08x_filter_id;
-#endif
-
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
}
@@ -1213,13 +1196,6 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
- pd.dma_tx = (void *)DMACH_SPI2_TX;
- pd.dma_rx = (void *)DMACH_SPI2_RX;
-#if defined(CONFIG_PL330_DMA)
- pd.filter = pl330_filter;
-#elif defined(CONFIG_S3C64XX_PL080)
- pd.filter = pl08x_filter_id;
-#endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
}
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index 6e4cd1867a9f..92eb5c3b486c 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -4,10 +4,76 @@
# Copyright (C) 2001 Russell King
#
+gen := arch/$(ARCH)/include/generated
+kapi := $(gen)/asm
+uapi := $(gen)/uapi/asm
+syshdr := $(srctree)/$(src)/syscallhdr.sh
+sysnr := $(srctree)/$(src)/syscallnr.sh
+systbl := $(srctree)/$(src)/syscalltbl.sh
+syscall := $(srctree)/$(src)/syscall.tbl
+
+gen-y := $(gen)/calls-oabi.S
+gen-y += $(gen)/calls-eabi.S
+kapi-hdrs-y := $(kapi)/unistd-nr.h
+kapi-hdrs-y += $(kapi)/mach-types.h
+uapi-hdrs-y := $(uapi)/unistd-common.h
+uapi-hdrs-y += $(uapi)/unistd-oabi.h
+uapi-hdrs-y += $(uapi)/unistd-eabi.h
+
+targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
+
+PHONY += kapi uapi
+
+kapi: $(kapi-hdrs-y) $(gen-y)
+
+uapi: $(uapi-hdrs-y)
+
+# Create output directory if not already present
+_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)') \
+ $(shell [ -d '$(uapi)' ] || mkdir -p '$(uapi)')
+
quiet_cmd_gen_mach = GEN $@
cmd_gen_mach = mkdir -p $(dir $@) && \
$(AWK) -f $(filter-out $(PHONY),$^) > $@ || \
{ rm -f $@; /bin/false; }
-include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types FORCE
+$(kapi)/mach-types.h: $(src)/gen-mach-types $(src)/mach-types FORCE
$(call if_changed,gen_mach)
+
+quiet_cmd_syshdr = SYSHDR $@
+ cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' '$<' '$@' \
+ '$(syshdr_abi_$(basetarget))' \
+ '$(syshdr_pfx_$(basetarget))' \
+ '__NR_SYSCALL_BASE'
+
+quiet_cmd_systbl = SYSTBL $@
+ cmd_systbl = $(CONFIG_SHELL) '$(systbl)' '$<' '$@' \
+ '$(systbl_abi_$(basetarget))'
+
+quiet_cmd_sysnr = SYSNR $@
+ cmd_sysnr = $(CONFIG_SHELL) '$(sysnr)' '$<' '$@' \
+ '$(syshdr_abi_$(basetarget))'
+
+syshdr_abi_unistd-common := common
+$(uapi)/unistd-common.h: $(syscall) $(syshdr) FORCE
+ $(call if_changed,syshdr)
+
+syshdr_abi_unistd-oabi := oabi
+$(uapi)/unistd-oabi.h: $(syscall) $(syshdr) FORCE
+ $(call if_changed,syshdr)
+
+syshdr_abi_unistd-eabi := eabi
+$(uapi)/unistd-eabi.h: $(syscall) $(syshdr) FORCE
+ $(call if_changed,syshdr)
+
+sysnr_abi_unistd-nr := common,oabi,eabi,compat
+$(kapi)/unistd-nr.h: $(syscall) $(sysnr) FORCE
+ $(call if_changed,sysnr)
+
+systbl_abi_calls-oabi := common,oabi
+$(gen)/calls-oabi.S: $(syscall) $(systbl) FORCE
+ $(call if_changed,systbl)
+
+systbl_abi_calls-eabi := common,eabi
+$(gen)/calls-eabi.S: $(syscall) $(systbl) FORCE
+ $(call if_changed,systbl)
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 2ed1b8a922ed..a9313b66f770 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -16,7 +16,7 @@
# are merged into mainline or have been edited in the machine database
# within the last 12 months. References to machine_is_NAME() do not count!
#
-# Last update: Fri Mar 22 17:24:50 2013
+# Last update: Sun Oct 30 20:21:01 2016
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -152,7 +152,6 @@ colibri MACH_COLIBRI COLIBRI 729
gateway7001 MACH_GATEWAY7001 GATEWAY7001 731
pcm027 MACH_PCM027 PCM027 732
anubis MACH_ANUBIS ANUBIS 734
-xboardgp8 MACH_XBOARDGP8 XBOARDGP8 742
akita MACH_AKITA AKITA 744
e330 MACH_E330 E330 753
nokia770 MACH_NOKIA770 NOKIA770 755
@@ -393,7 +392,6 @@ anw6410 MACH_ANW6410 ANW6410 2183
imx27_visstrim_m10 MACH_IMX27_VISSTRIM_M10 IMX27_VISSTRIM_M10 2187
portuxg20 MACH_PORTUXG20 PORTUXG20 2191
smdkc110 MACH_SMDKC110 SMDKC110 2193
-cabespresso MACH_CABESPRESSO CABESPRESSO 2194
omap3517evm MACH_OMAP3517EVM OMAP3517EVM 2200
netspace_v2 MACH_NETSPACE_V2 NETSPACE_V2 2201
netspace_max_v2 MACH_NETSPACE_MAX_V2 NETSPACE_MAX_V2 2202
@@ -412,7 +410,6 @@ bigdisk MACH_BIGDISK BIGDISK 2283
at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288
bcmring MACH_BCMRING BCMRING 2289
mahimahi MACH_MAHIMAHI MAHIMAHI 2304
-cerebric MACH_CEREBRIC CEREBRIC 2311
smdk6442 MACH_SMDK6442 SMDK6442 2324
openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325
devkit8000 MACH_DEVKIT8000 DEVKIT8000 2330
@@ -435,9 +432,7 @@ tnetv107x MACH_TNETV107X TNETV107X 2418
smdkv210 MACH_SMDKV210 SMDKV210 2456
omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464
omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465
-cybook2440 MACH_CYBOOK2440 CYBOOK2440 2466
smartq7 MACH_SMARTQ7 SMARTQ7 2479
-watson_efm_plugin MACH_WATSON_EFM_PLUGIN WATSON_EFM_PLUGIN 2491
g4evm MACH_G4EVM G4EVM 2493
omapl138_hawkboard MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD 2495
ts41x MACH_TS41X TS41X 2502
@@ -472,7 +467,6 @@ igep0030 MACH_IGEP0030 IGEP0030 2717
sbc3530 MACH_SBC3530 SBC3530 2722
saarb MACH_SAARB SAARB 2727
harmony MACH_HARMONY HARMONY 2731
-cybook_orizon MACH_CYBOOK_ORIZON CYBOOK_ORIZON 2733
msm7x30_fluid MACH_MSM7X30_FLUID MSM7X30_FLUID 2741
cm_t3517 MACH_CM_T3517 CM_T3517 2750
wbd222 MACH_WBD222 WBD222 2753
@@ -490,6 +484,7 @@ eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
smdkc210 MACH_SMDKC210 SMDKC210 2838
t5325 MACH_T5325 T5325 2846
income MACH_INCOME INCOME 2849
+meson MACH_MESON MESON 2853
goni MACH_GONI GONI 2862
bv07 MACH_BV07 BV07 2882
openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884
@@ -523,9 +518,9 @@ prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
paz00 MACH_PAZ00 PAZ00 3128
acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
ag5evm MACH_AG5EVM AG5EVM 3189
-ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
trimslice MACH_TRIMSLICE TRIMSLICE 3209
+mackerel MACH_MACKEREL MACKEREL 3211
kaen MACH_KAEN KAEN 3217
nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
@@ -540,469 +535,66 @@ snowball MACH_SNOWBALL SNOWBALL 3363
xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378
nuri MACH_NURI NURI 3379
origen MACH_ORIGEN ORIGEN 3455
+xarina MACH_XARINA XARINA 3476
nspire MACH_NSPIRE NSPIRE 3503
nokia_rm696 MACH_NOKIA_RM696 NOKIA_RM696 3522
-mikrap_x168 MACH_MIKRAP_X168 MIKRAP_X168 3543
-deto_macarm9 MACH_DETO_MACARM9 DETO_MACARM9 3568
m28evk MACH_M28EVK M28EVK 3613
kota2 MACH_KOTA2 KOTA2 3616
bonito MACH_BONITO BONITO 3623
-omap3_egf MACH_OMAP3_EGF OMAP3_EGF 3637
smdk4212 MACH_SMDK4212 SMDK4212 3638
apx4devkit MACH_APX4DEVKIT APX4DEVKIT 3712
smdk4412 MACH_SMDK4412 SMDK4412 3765
marzen MACH_MARZEN MARZEN 3790
-krome MACH_KROME KROME 3797
-armadillo800eva MACH_ARMADILLO800EVA ARMADILLO800EVA 3863
-mx53_umobo MACH_MX53_UMOBO MX53_UMOBO 3927
-mt4 MACH_MT4 MT4 3981
+empc_a500 MACH_EMPC_A500 EMPC_A500 3848
u8520 MACH_U8520 U8520 3990
-chupacabra MACH_CHUPACABRA CHUPACABRA 4098
-scorpion MACH_SCORPION SCORPION 4099
-davinci_he_hmi10 MACH_DAVINCI_HE_HMI10 DAVINCI_HE_HMI10 4100
-topkick MACH_TOPKICK TOPKICK 4101
-m3_auguestrush MACH_M3_AUGUESTRUSH M3_AUGUESTRUSH 4102
-ipc335x MACH_IPC335X IPC335X 4103
-sun4i MACH_SUN4I SUN4I 4104
-imx233_olinuxino MACH_IMX233_OLINUXINO IMX233_OLINUXINO 4105
-k2_wl MACH_K2_WL K2_WL 4106
-k2_ul MACH_K2_UL K2_UL 4107
-k2_cl MACH_K2_CL K2_CL 4108
-minbari_w MACH_MINBARI_W MINBARI_W 4109
-minbari_m MACH_MINBARI_M MINBARI_M 4110
-k035 MACH_K035 K035 4111
-ariel MACH_ARIEL ARIEL 4112
-arielsaarc MACH_ARIELSAARC ARIELSAARC 4113
-arieldkb MACH_ARIELDKB ARIELDKB 4114
-armadillo810 MACH_ARMADILLO810 ARMADILLO810 4115
-tam335x MACH_TAM335X TAM335X 4116
-grouper MACH_GROUPER GROUPER 4117
-mpcsa21_9g20 MACH_MPCSA21_9G20 MPCSA21_9G20 4118
-m6u_cpu MACH_M6U_CPU M6U_CPU 4119
-ginkgo MACH_GINKGO GINKGO 4121
-cgt_qmx6 MACH_CGT_QMX6 CGT_QMX6 4122
-profpga MACH_PROFPGA PROFPGA 4123
-acfx100oc MACH_ACFX100OC ACFX100OC 4124
-acfx100nb MACH_ACFX100NB ACFX100NB 4125
-capricorn MACH_CAPRICORN CAPRICORN 4126
-pisces MACH_PISCES PISCES 4127
-aries MACH_ARIES ARIES 4128
-cancer MACH_CANCER CANCER 4129
-leo MACH_LEO LEO 4130
-virgo MACH_VIRGO VIRGO 4131
-sagittarius MACH_SAGITTARIUS SAGITTARIUS 4132
-devil MACH_DEVIL DEVIL 4133
-ballantines MACH_BALLANTINES BALLANTINES 4134
-omap3_procerusvpu MACH_OMAP3_PROCERUSVPU OMAP3_PROCERUSVPU 4135
-my27 MACH_MY27 MY27 4136
-sun6i MACH_SUN6I SUN6I 4137
-sun5i MACH_SUN5I SUN5I 4138
-mx512_mx MACH_MX512_MX MX512_MX 4139
-kzm9g MACH_KZM9G KZM9G 4140
-vdstbn MACH_VDSTBN VDSTBN 4141
-cfa10036 MACH_CFA10036 CFA10036 4142
-cfa10049 MACH_CFA10049 CFA10049 4143
-pcm051 MACH_PCM051 PCM051 4144
-vybrid_vf7xx MACH_VYBRID_VF7XX VYBRID_VF7XX 4145
-vybrid_vf6xx MACH_VYBRID_VF6XX VYBRID_VF6XX 4146
-vybrid_vf5xx MACH_VYBRID_VF5XX VYBRID_VF5XX 4147
-vybrid_vf4xx MACH_VYBRID_VF4XX VYBRID_VF4XX 4148
-aria_g25 MACH_ARIA_G25 ARIA_G25 4149
-bcm21553 MACH_BCM21553 BCM21553 4150
-smdk5410 MACH_SMDK5410 SMDK5410 4151
-lpc18xx MACH_LPC18XX LPC18XX 4152
-oratisparty MACH_ORATISPARTY ORATISPARTY 4153
-qseven MACH_QSEVEN QSEVEN 4154
-gmv_generic MACH_GMV_GENERIC GMV_GENERIC 4155
-th_link_eth MACH_TH_LINK_ETH TH_LINK_ETH 4156
-tn_muninn MACH_TN_MUNINN TN_MUNINN 4157
-rampage MACH_RAMPAGE RAMPAGE 4158
-visstrim_mv10 MACH_VISSTRIM_MV10 VISSTRIM_MV10 4159
-mx28_wilma MACH_MX28_WILMA MX28_WILMA 4164
-msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166
-vpu101 MACH_VPU101 VPU101 4167
-baileys MACH_BAILEYS BAILEYS 4169
-familybox MACH_FAMILYBOX FAMILYBOX 4170
-ensemble_mx35 MACH_ENSEMBLE_MX35 ENSEMBLE_MX35 4171
-sc_sps_1 MACH_SC_SPS_1 SC_SPS_1 4172
-ucsimply_sam9260 MACH_UCSIMPLY_SAM9260 UCSIMPLY_SAM9260 4173
-unicorn MACH_UNICORN UNICORN 4174
-m9g45a MACH_M9G45A M9G45A 4175
-mtwebif MACH_MTWEBIF MTWEBIF 4176
-playstone MACH_PLAYSTONE PLAYSTONE 4177
-chelsea MACH_CHELSEA CHELSEA 4178
-bayern MACH_BAYERN BAYERN 4179
-mitwo MACH_MITWO MITWO 4180
-mx25_noah MACH_MX25_NOAH MX25_NOAH 4181
-stm_b2020 MACH_STM_B2020 STM_B2020 4182
-annax_src MACH_ANNAX_SRC ANNAX_SRC 4183
-ionics_stratus MACH_IONICS_STRATUS IONICS_STRATUS 4184
-hugo MACH_HUGO HUGO 4185
-em300 MACH_EM300 EM300 4186
-mmp3_qseven MACH_MMP3_QSEVEN MMP3_QSEVEN 4187
-bosphorus2 MACH_BOSPHORUS2 BOSPHORUS2 4188
-tt2200 MACH_TT2200 TT2200 4189
-ocelot3 MACH_OCELOT3 OCELOT3 4190
-tek_cobra MACH_TEK_COBRA TEK_COBRA 4191
-protou MACH_PROTOU PROTOU 4192
-msm8625_evt MACH_MSM8625_EVT MSM8625_EVT 4193
-mx53_sellwood MACH_MX53_SELLWOOD MX53_SELLWOOD 4194
-somiq_am35 MACH_SOMIQ_AM35 SOMIQ_AM35 4195
-somiq_am37 MACH_SOMIQ_AM37 SOMIQ_AM37 4196
-k2_plc_cl MACH_K2_PLC_CL K2_PLC_CL 4197
-tc2 MACH_TC2 TC2 4198
-dulex_j MACH_DULEX_J DULEX_J 4199
-stm_b2044 MACH_STM_B2044 STM_B2044 4200
-deluxe_j MACH_DELUXE_J DELUXE_J 4201
-mango2443 MACH_MANGO2443 MANGO2443 4202
-cp2dcg MACH_CP2DCG CP2DCG 4203
-cp2dtg MACH_CP2DTG CP2DTG 4204
-cp2dug MACH_CP2DUG CP2DUG 4205
-var_som_am33 MACH_VAR_SOM_AM33 VAR_SOM_AM33 4206
-pepper MACH_PEPPER PEPPER 4207
-mango2450 MACH_MANGO2450 MANGO2450 4208
-valente_wx_c9 MACH_VALENTE_WX_C9 VALENTE_WX_C9 4209
-minitv MACH_MINITV MINITV 4210
-u8540 MACH_U8540 U8540 4211
-iv_atlas_i_z7e MACH_IV_ATLAS_I_Z7E IV_ATLAS_I_Z7E 4212
-mach_type_sky MACH_MACH_TYPE_SKY MACH_TYPE_SKY 4214
-bluesky MACH_BLUESKY BLUESKY 4215
-ngrouter MACH_NGROUTER NGROUTER 4216
-mx53_denetim MACH_MX53_DENETIM MX53_DENETIM 4217
-opal MACH_OPAL OPAL 4218
-gnet_us3gref MACH_GNET_US3GREF GNET_US3GREF 4219
-gnet_nc3g MACH_GNET_NC3G GNET_NC3G 4220
-gnet_ge3g MACH_GNET_GE3G GNET_GE3G 4221
-adp2 MACH_ADP2 ADP2 4222
-tqma28 MACH_TQMA28 TQMA28 4223
-kacom3 MACH_KACOM3 KACOM3 4224
-rrhdemo MACH_RRHDEMO RRHDEMO 4225
-protodug MACH_PROTODUG PROTODUG 4226
-lago MACH_LAGO LAGO 4227
-ktt30 MACH_KTT30 KTT30 4228
-ts43xx MACH_TS43XX TS43XX 4229
-mx6q_denso MACH_MX6Q_DENSO MX6Q_DENSO 4230
-comsat_gsmumts8 MACH_COMSAT_GSMUMTS8 COMSAT_GSMUMTS8 4231
-dreamx MACH_DREAMX DREAMX 4232
-thunderstonem MACH_THUNDERSTONEM THUNDERSTONEM 4233
-yoyopad MACH_YOYOPAD YOYOPAD 4234
-yoyopatient MACH_YOYOPATIENT YOYOPATIENT 4235
-a10l MACH_A10L A10L 4236
-mq60 MACH_MQ60 MQ60 4237
-linkstation_lsql MACH_LINKSTATION_LSQL LINKSTATION_LSQL 4238
-am3703gateway MACH_AM3703GATEWAY AM3703GATEWAY 4239
-accipiter MACH_ACCIPITER ACCIPITER 4240
-magnidug MACH_MAGNIDUG MAGNIDUG 4242
-hydra MACH_HYDRA HYDRA 4243
-sun3i MACH_SUN3I SUN3I 4244
-stm_b2078 MACH_STM_B2078 STM_B2078 4245
-at91sam9263deskv2 MACH_AT91SAM9263DESKV2 AT91SAM9263DESKV2 4246
-deluxe_r MACH_DELUXE_R DELUXE_R 4247
-p_98_v MACH_P_98_V P_98_V 4248
-p_98_c MACH_P_98_C P_98_C 4249
-davinci_am18xx_omn MACH_DAVINCI_AM18XX_OMN DAVINCI_AM18XX_OMN 4250
-socfpga_cyclone5 MACH_SOCFPGA_CYCLONE5 SOCFPGA_CYCLONE5 4251
-cabatuin MACH_CABATUIN CABATUIN 4252
-yoyopad_ft MACH_YOYOPAD_FT YOYOPAD_FT 4253
-dan2400evb MACH_DAN2400EVB DAN2400EVB 4254
-dan3400evb MACH_DAN3400EVB DAN3400EVB 4255
-edm_sf_imx6 MACH_EDM_SF_IMX6 EDM_SF_IMX6 4256
-edm_cf_imx6 MACH_EDM_CF_IMX6 EDM_CF_IMX6 4257
-vpos3xx MACH_VPOS3XX VPOS3XX 4258
-vulcano_9x5 MACH_VULCANO_9X5 VULCANO_9X5 4259
-spmp8000 MACH_SPMP8000 SPMP8000 4260
-catalina MACH_CATALINA CATALINA 4261
-rd88f5181l_fe MACH_RD88F5181L_FE RD88F5181L_FE 4262
-mx535_mx MACH_MX535_MX MX535_MX 4263
-armadillo840 MACH_ARMADILLO840 ARMADILLO840 4264
-spc9000baseboard MACH_SPC9000BASEBOARD SPC9000BASEBOARD 4265
-iris MACH_IRIS IRIS 4266
-protodcg MACH_PROTODCG PROTODCG 4267
-palmtree MACH_PALMTREE PALMTREE 4268
-novena MACH_NOVENA NOVENA 4269
-ma_um MACH_MA_UM MA_UM 4270
-ma_am MACH_MA_AM MA_AM 4271
-ems348 MACH_EMS348 EMS348 4272
-cm_fx6 MACH_CM_FX6 CM_FX6 4273
-arndale MACH_ARNDALE ARNDALE 4274
-q5xr5 MACH_Q5XR5 Q5XR5 4275
-willow MACH_WILLOW WILLOW 4276
-omap3621_odyv3 MACH_OMAP3621_ODYV3 OMAP3621_ODYV3 4277
-omapl138_presonus MACH_OMAPL138_PRESONUS OMAPL138_PRESONUS 4278
-dvf99 MACH_DVF99 DVF99 4279
-impression_j MACH_IMPRESSION_J IMPRESSION_J 4280
-qblissa9 MACH_QBLISSA9 QBLISSA9 4281
-robin_heliview10 MACH_ROBIN_HELIVIEW10 ROBIN_HELIVIEW10 4282
-sun7i MACH_SUN7I SUN7I 4283
-mx6q_hdmidongle MACH_MX6Q_HDMIDONGLE MX6Q_HDMIDONGLE 4284
-mx6_sid2 MACH_MX6_SID2 MX6_SID2 4285
-helios_v3 MACH_HELIOS_V3 HELIOS_V3 4286
-helios_v4 MACH_HELIOS_V4 HELIOS_V4 4287
-q7_imx6 MACH_Q7_IMX6 Q7_IMX6 4288
-odroidx MACH_ODROIDX ODROIDX 4289
-robpro MACH_ROBPRO ROBPRO 4290
-research59if_mk1 MACH_RESEARCH59IF_MK1 RESEARCH59IF_MK1 4291
-bobsleigh MACH_BOBSLEIGH BOBSLEIGH 4292
-dcshgwt3 MACH_DCSHGWT3 DCSHGWT3 4293
-gld1018 MACH_GLD1018 GLD1018 4294
-ev10 MACH_EV10 EV10 4295
-nitrogen6x MACH_NITROGEN6X NITROGEN6X 4296
-p_107_bb MACH_P_107_BB P_107_BB 4297
-evita_utl MACH_EVITA_UTL EVITA_UTL 4298
-falconwing MACH_FALCONWING FALCONWING 4299
-dct3 MACH_DCT3 DCT3 4300
-cpx2e_cell MACH_CPX2E_CELL CPX2E_CELL 4301
-amiro MACH_AMIRO AMIRO 4302
-mx6q_brassboard MACH_MX6Q_BRASSBOARD MX6Q_BRASSBOARD 4303
-dalmore MACH_DALMORE DALMORE 4304
-omap3_portal7cp MACH_OMAP3_PORTAL7CP OMAP3_PORTAL7CP 4305
-tegra_pluto MACH_TEGRA_PLUTO TEGRA_PLUTO 4306
-mx6sl_evk MACH_MX6SL_EVK MX6SL_EVK 4307
-m7 MACH_M7 M7 4308
-pxm2 MACH_PXM2 PXM2 4309
-haba_knx_lite MACH_HABA_KNX_LITE HABA_KNX_LITE 4310
-tai MACH_TAI TAI 4311
-prototd MACH_PROTOTD PROTOTD 4312
-dst_tonto MACH_DST_TONTO DST_TONTO 4313
-draco MACH_DRACO DRACO 4314
-dxr2 MACH_DXR2 DXR2 4315
-rut MACH_RUT RUT 4316
-am180x_wsc MACH_AM180X_WSC AM180X_WSC 4317
-deluxe_u MACH_DELUXE_U DELUXE_U 4318
-deluxe_ul MACH_DELUXE_UL DELUXE_UL 4319
-at91sam9260medths MACH_AT91SAM9260MEDTHS AT91SAM9260MEDTHS 4320
-matrix516 MACH_MATRIX516 MATRIX516 4321
-vid401x MACH_VID401X VID401X 4322
-helios_v5 MACH_HELIOS_V5 HELIOS_V5 4323
-playpaq2 MACH_PLAYPAQ2 PLAYPAQ2 4324
-igam MACH_IGAM IGAM 4325
-amico_i MACH_AMICO_I AMICO_I 4326
-amico_e MACH_AMICO_E AMICO_E 4327
-sentient_mm3_ck MACH_SENTIENT_MM3_CK SENTIENT_MM3_CK 4328
-smx6 MACH_SMX6 SMX6 4329
-pango MACH_PANGO PANGO 4330
-ns115_stick MACH_NS115_STICK NS115_STICK 4331
-bctrm3 MACH_BCTRM3 BCTRM3 4332
-doctorws MACH_DOCTORWS DOCTORWS 4333
-m2601 MACH_M2601 M2601 4334
-vgg1111 MACH_VGG1111 VGG1111 4337
-countach MACH_COUNTACH COUNTACH 4338
-visstrim_sm20 MACH_VISSTRIM_SM20 VISSTRIM_SM20 4339
-a639 MACH_A639 A639 4340
-spacemonkey MACH_SPACEMONKEY SPACEMONKEY 4341
-zpdu_stamp MACH_ZPDU_STAMP ZPDU_STAMP 4342
-htc_g7_clone MACH_HTC_G7_CLONE HTC_G7_CLONE 4343
-ft2080_corvus MACH_FT2080_CORVUS FT2080_CORVUS 4344
-fisland MACH_FISLAND FISLAND 4345
-zpdu MACH_ZPDU ZPDU 4346
urt MACH_URT URT 4347
-conti_ovip MACH_CONTI_OVIP CONTI_OVIP 4348
-omapl138_nagra MACH_OMAPL138_NAGRA OMAPL138_NAGRA 4349
-da850_at3kp1 MACH_DA850_AT3KP1 DA850_AT3KP1 4350
-da850_at3kp2 MACH_DA850_AT3KP2 DA850_AT3KP2 4351
-surma MACH_SURMA SURMA 4352
-stm_b2092 MACH_STM_B2092 STM_B2092 4353
-mx535_ycr MACH_MX535_YCR MX535_YCR 4354
-m7_wl MACH_M7_WL M7_WL 4355
-m7_u MACH_M7_U M7_U 4356
-omap3_stndt_evm MACH_OMAP3_STNDT_EVM OMAP3_STNDT_EVM 4357
-m7_wlv MACH_M7_WLV M7_WLV 4358
-xam3517 MACH_XAM3517 XAM3517 4359
-a220 MACH_A220 A220 4360
-aclima_odie MACH_ACLIMA_ODIE ACLIMA_ODIE 4361
-vibble MACH_VIBBLE VIBBLE 4362
-k2_u MACH_K2_U K2_U 4363
-mx53_egf MACH_MX53_EGF MX53_EGF 4364
-novpek_imx53 MACH_NOVPEK_IMX53 NOVPEK_IMX53 4365
-novpek_imx6x MACH_NOVPEK_IMX6X NOVPEK_IMX6X 4366
-mx25_smartbox MACH_MX25_SMARTBOX MX25_SMARTBOX 4367
-eicg6410 MACH_EICG6410 EICG6410 4368
-picasso_e3 MACH_PICASSO_E3 PICASSO_E3 4369
-motonavigator MACH_MOTONAVIGATOR MOTONAVIGATOR 4370
-varioconnect2 MACH_VARIOCONNECT2 VARIOCONNECT2 4371
-deluxe_tw MACH_DELUXE_TW DELUXE_TW 4372
-kore3 MACH_KORE3 KORE3 4374
-mx6s_drs MACH_MX6S_DRS MX6S_DRS 4375
-cmimx6 MACH_CMIMX6 CMIMX6 4376
-roth MACH_ROTH ROTH 4377
-eq4ux MACH_EQ4UX EQ4UX 4378
-x1plus MACH_X1PLUS X1PLUS 4379
-modimx27 MACH_MODIMX27 MODIMX27 4380
-videon_hduac MACH_VIDEON_HDUAC VIDEON_HDUAC 4381
-blackbird MACH_BLACKBIRD BLACKBIRD 4382
-runmaster MACH_RUNMASTER RUNMASTER 4383
-ceres MACH_CERES CERES 4384
-nad435 MACH_NAD435 NAD435 4385
-ns115_proto_type MACH_NS115_PROTO_TYPE NS115_PROTO_TYPE 4386
-fs20_vcc MACH_FS20_VCC FS20_VCC 4387
-meson6tv_skt MACH_MESON6TV_SKT MESON6TV_SKT 4389
keystone MACH_KEYSTONE KEYSTONE 4390
-pcm052 MACH_PCM052 PCM052 4391
-qrd_skud_prime MACH_QRD_SKUD_PRIME QRD_SKUD_PRIME 4393
-guf_santaro MACH_GUF_SANTARO GUF_SANTARO 4395
-sheepshead MACH_SHEEPSHEAD SHEEPSHEAD 4396
-mx6_iwg15m_mxm MACH_MX6_IWG15M_MXM MX6_IWG15M_MXM 4397
-mx6_iwg15m_q7 MACH_MX6_IWG15M_Q7 MX6_IWG15M_Q7 4398
-at91sam9263if8mic MACH_AT91SAM9263IF8MIC AT91SAM9263IF8MIC 4399
-marcopolo MACH_MARCOPOLO MARCOPOLO 4401
-mx535_sdcr MACH_MX535_SDCR MX535_SDCR 4402
-mx53_csb2733 MACH_MX53_CSB2733 MX53_CSB2733 4403
-diva MACH_DIVA DIVA 4404
-ncr_7744 MACH_NCR_7744 NCR_7744 4405
-macallan MACH_MACALLAN MACALLAN 4406
-wnr3500 MACH_WNR3500 WNR3500 4407
-pgavrf MACH_PGAVRF PGAVRF 4408
-helios_v6 MACH_HELIOS_V6 HELIOS_V6 4409
-lcct MACH_LCCT LCCT 4410
-csndug MACH_CSNDUG CSNDUG 4411
-wandboard_imx6 MACH_WANDBOARD_IMX6 WANDBOARD_IMX6 4412
-omap4_jet MACH_OMAP4_JET OMAP4_JET 4413
-tegra_roth MACH_TEGRA_ROTH TEGRA_ROTH 4414
-m7dcg MACH_M7DCG M7DCG 4415
-m7dug MACH_M7DUG M7DUG 4416
-m7dtg MACH_M7DTG M7DTG 4417
-ap42x MACH_AP42X AP42X 4418
-var_som_mx6 MACH_VAR_SOM_MX6 VAR_SOM_MX6 4419
-pdlu MACH_PDLU PDLU 4420
-hydrogen MACH_HYDROGEN HYDROGEN 4421
-npa211e MACH_NPA211E NPA211E 4422
-arcadia MACH_ARCADIA ARCADIA 4423
-arcadia_l MACH_ARCADIA_L ARCADIA_L 4424
-msm8930dt MACH_MSM8930DT MSM8930DT 4425
-ktam3874 MACH_KTAM3874 KTAM3874 4426
-cec4 MACH_CEC4 CEC4 4427
-ape6evm MACH_APE6EVM APE6EVM 4428
-tx6 MACH_TX6 TX6 4429
-cfa10037 MACH_CFA10037 CFA10037 4431
-ezp1000 MACH_EZP1000 EZP1000 4433
-wgr826v MACH_WGR826V WGR826V 4434
-exuma MACH_EXUMA EXUMA 4435
-fregate MACH_FREGATE FREGATE 4436
-osirisimx508 MACH_OSIRISIMX508 OSIRISIMX508 4437
-st_exigo MACH_ST_EXIGO ST_EXIGO 4438
-pismo MACH_PISMO PISMO 4439
-atc7 MACH_ATC7 ATC7 4440
-nspireclp MACH_NSPIRECLP NSPIRECLP 4441
-nspiretp MACH_NSPIRETP NSPIRETP 4442
-nspirecx MACH_NSPIRECX NSPIRECX 4443
-maya MACH_MAYA MAYA 4444
-wecct MACH_WECCT WECCT 4445
-m2s MACH_M2S M2S 4446
-msm8625q_evbd MACH_MSM8625Q_EVBD MSM8625Q_EVBD 4447
-tiny210 MACH_TINY210 TINY210 4448
-g3 MACH_G3 G3 4449
-hurricane MACH_HURRICANE HURRICANE 4450
-mx6_pod MACH_MX6_POD MX6_POD 4451
-elondcn MACH_ELONDCN ELONDCN 4452
-cwmx535 MACH_CWMX535 CWMX535 4453
-m7_wlj MACH_M7_WLJ M7_WLJ 4454
-qsp_arm MACH_QSP_ARM QSP_ARM 4455
-msm8625q_skud MACH_MSM8625Q_SKUD MSM8625Q_SKUD 4456
-htcmondrian MACH_HTCMONDRIAN HTCMONDRIAN 4457
-watson_ead MACH_WATSON_EAD WATSON_EAD 4458
-mitwoa MACH_MITWOA MITWOA 4459
-omap3_wolverine MACH_OMAP3_WOLVERINE OMAP3_WOLVERINE 4460
-mapletree MACH_MAPLETREE MAPLETREE 4461
-msm8625_fih_sae MACH_MSM8625_FIH_SAE MSM8625_FIH_SAE 4462
-epc35 MACH_EPC35 EPC35 4463
-smartrtu MACH_SMARTRTU SMARTRTU 4464
-rcm101 MACH_RCM101 RCM101 4465
-amx_imx53_mxx MACH_AMX_IMX53_MXX AMX_IMX53_MXX 4466
-acer_a12 MACH_ACER_A12 ACER_A12 4470
-sbc6x MACH_SBC6X SBC6X 4471
-u2 MACH_U2 U2 4472
-smdk4270 MACH_SMDK4270 SMDK4270 4473
-priscillag MACH_PRISCILLAG PRISCILLAG 4474
-priscillac MACH_PRISCILLAC PRISCILLAC 4475
-priscilla MACH_PRISCILLA PRISCILLA 4476
-innova_shpu_v2 MACH_INNOVA_SHPU_V2 INNOVA_SHPU_V2 4477
-mach_type_dep2410 MACH_MACH_TYPE_DEP2410 MACH_TYPE_DEP2410 4479
-bctre3 MACH_BCTRE3 BCTRE3 4480
-omap_m100 MACH_OMAP_M100 OMAP_M100 4481
-flo MACH_FLO FLO 4482
-nanobone MACH_NANOBONE NANOBONE 4483
-stm_b2105 MACH_STM_B2105 STM_B2105 4484
-omap4_bsc_bap_v3 MACH_OMAP4_BSC_BAP_V3 OMAP4_BSC_BAP_V3 4485
-ss1pam MACH_SS1PAM SS1PAM 4486
-primominiu MACH_PRIMOMINIU PRIMOMINIU 4488
-mrt_35hd_dualnas_e MACH_MRT_35HD_DUALNAS_E MRT_35HD_DUALNAS_E 4489
-kiwi MACH_KIWI KIWI 4490
-hw90496 MACH_HW90496 HW90496 4491
-mep2440 MACH_MEP2440 MEP2440 4492
-colibri_t30 MACH_COLIBRI_T30 COLIBRI_T30 4493
-cwv1 MACH_CWV1 CWV1 4494
-nsa325 MACH_NSA325 NSA325 4495
-dpxmtc MACH_DPXMTC DPXMTC 4497
-tt_stuttgart MACH_TT_STUTTGART TT_STUTTGART 4498
-miranda_apcii MACH_MIRANDA_APCII MIRANDA_APCII 4499
-mx6q_moderox MACH_MX6Q_MODEROX MX6Q_MODEROX 4500
-mudskipper MACH_MUDSKIPPER MUDSKIPPER 4501
-urania MACH_URANIA URANIA 4502
-stm_b2112 MACH_STM_B2112 STM_B2112 4503
-mx6q_ats_phoenix MACH_MX6Q_ATS_PHOENIX MX6Q_ATS_PHOENIX 4505
-stm_b2116 MACH_STM_B2116 STM_B2116 4506
-mythology MACH_MYTHOLOGY MYTHOLOGY 4507
-fc360v1 MACH_FC360V1 FC360V1 4508
-gps_sensor MACH_GPS_SENSOR GPS_SENSOR 4509
-gazelle MACH_GAZELLE GAZELLE 4510
-mpq8064_dma MACH_MPQ8064_DMA MPQ8064_DMA 4511
-wems_asd01 MACH_WEMS_ASD01 WEMS_ASD01 4512
-apalis_t30 MACH_APALIS_T30 APALIS_T30 4513
-armstonea9 MACH_ARMSTONEA9 ARMSTONEA9 4515
-omap_blazetablet MACH_OMAP_BLAZETABLET OMAP_BLAZETABLET 4516
-ar6mxq MACH_AR6MXQ AR6MXQ 4517
-ar6mxs MACH_AR6MXS AR6MXS 4518
-gwventana MACH_GWVENTANA GWVENTANA 4520
-igep0033 MACH_IGEP0033 IGEP0033 4521
-h52c1_concerto MACH_H52C1_CONCERTO H52C1_CONCERTO 4524
-fcmbrd MACH_FCMBRD FCMBRD 4525
-pcaaxs1 MACH_PCAAXS1 PCAAXS1 4526
-ls_orca MACH_LS_ORCA LS_ORCA 4527
-pcm051lb MACH_PCM051LB PCM051LB 4528
-mx6s_lp507_gvci MACH_MX6S_LP507_GVCI MX6S_LP507_GVCI 4529
-dido MACH_DIDO DIDO 4530
-swarco_itc3_9g20 MACH_SWARCO_ITC3_9G20 SWARCO_ITC3_9G20 4531
-robo_roady MACH_ROBO_ROADY ROBO_ROADY 4532
-rskrza1 MACH_RSKRZA1 RSKRZA1 4533
-swarco_sid MACH_SWARCO_SID SWARCO_SID 4534
-mx6_iwg15s_sbc MACH_MX6_IWG15S_SBC MX6_IWG15S_SBC 4535
-mx6q_camaro MACH_MX6Q_CAMARO MX6Q_CAMARO 4536
-hb6mxs MACH_HB6MXS HB6MXS 4537
-lager MACH_LAGER LAGER 4538
-lp8x4x MACH_LP8X4X LP8X4X 4539
-tegratab7 MACH_TEGRATAB7 TEGRATAB7 4540
-andromeda MACH_ANDROMEDA ANDROMEDA 4541
-bootes MACH_BOOTES BOOTES 4542
-nethmi MACH_NETHMI NETHMI 4543
-tegratab MACH_TEGRATAB TEGRATAB 4544
-som5_evb MACH_SOM5_EVB SOM5_EVB 4545
-venaticorum MACH_VENATICORUM VENATICORUM 4546
-stm_b2110 MACH_STM_B2110 STM_B2110 4547
-elux_hathor MACH_ELUX_HATHOR ELUX_HATHOR 4548
-helios_v7 MACH_HELIOS_V7 HELIOS_V7 4549
-xc10v1 MACH_XC10V1 XC10V1 4550
-cp2u MACH_CP2U CP2U 4551
-iap_f MACH_IAP_F IAP_F 4552
-iap_g MACH_IAP_G IAP_G 4553
-aae MACH_AAE AAE 4554
-pegasus MACH_PEGASUS PEGASUS 4555
-cygnus MACH_CYGNUS CYGNUS 4556
-centaurus MACH_CENTAURUS CENTAURUS 4557
-msm8930_qrd8930 MACH_MSM8930_QRD8930 MSM8930_QRD8930 4558
-quby_tim MACH_QUBY_TIM QUBY_TIM 4559
-zedi3250a MACH_ZEDI3250A ZEDI3250A 4560
-grus MACH_GRUS GRUS 4561
-apollo3 MACH_APOLLO3 APOLLO3 4562
-cowon_r7 MACH_COWON_R7 COWON_R7 4563
-tonga3 MACH_TONGA3 TONGA3 4564
-p535 MACH_P535 P535 4565
-sa3874i MACH_SA3874I SA3874I 4566
-mx6_navico_com MACH_MX6_NAVICO_COM MX6_NAVICO_COM 4567
-proxmobil2 MACH_PROXMOBIL2 PROXMOBIL2 4568
-ubinux1 MACH_UBINUX1 UBINUX1 4569
-istos MACH_ISTOS ISTOS 4570
-benvolio4 MACH_BENVOLIO4 BENVOLIO4 4571
-eco5_bx2 MACH_ECO5_BX2 ECO5_BX2 4572
-eukrea_cpuimx28sd MACH_EUKREA_CPUIMX28SD EUKREA_CPUIMX28SD 4573
-domotab MACH_DOMOTAB DOMOTAB 4574
-pfla03 MACH_PFLA03 PFLA03 4575
+ckb_rza1h MACH_CKB_RZA1H CKB_RZA1H 4780
+bcm2835 MACH_BCM2835 BCM2835 4828
+cm_3g MACH_CM_3G CM_3G 4943
+empc_aimx6 MACH_EMPC_AIMX6 EMPC_AIMX6 4958
+diyefis6410 MACH_DIYEFIS6410 DIYEFIS6410 5063
+mx53_turing MACH_MX53_TURING MX53_TURING 5064
+mx6dl_turing MACH_MX6DL_TURING MX6DL_TURING 5066
+mx53_indash MACH_MX53_INDASH MX53_INDASH 5067
+mx6q_indash MACH_MX6Q_INDASH MX6Q_INDASH 5068
+mx6dl_indash MACH_MX6DL_INDASH MX6DL_INDASH 5069
+rts_g6 MACH_RTS_G6 RTS_G6 5070
+ka_titan MACH_KA_TITAN KA_TITAN 5071
+cl_som_imx7 MACH_CL_SOM_IMX7 CL_SOM_IMX7 5072
+vvdn_mgsi_vsis MACH_VVDN_MGSI_VSIS VVDN_MGSI_VSIS 5073
+mx6q_nano MACH_MX6Q_NANO MX6Q_NANO 5074
+pdu001 MACH_PDU001 PDU001 5075
+cab_proyk MACH_CAB_PROYK CAB_PROYK 5076
+klin MACH_KLIN KLIN 5077
+enman_steuerbox MACH_ENMAN_STEUERBOX ENMAN_STEUERBOX 5078
+ls_stingray MACH_LS_STINGRAY LS_STINGRAY 5079
+ipdu MACH_IPDU IPDU 5080
+linda MACH_LINDA LINDA 5081
+mx6q_openrex MACH_MX6Q_OPENREX MX6Q_OPENREX 5082
+on100 MACH_ON100 ON100 5083
+eminds_rtu12 MACH_EMINDS_RTU12 EMINDS_RTU12 5084
+eminds_avl10 MACH_EMINDS_AVL10 EMINDS_AVL10 5085
+main_plc_lme MACH_MAIN_PLC_LME MAIN_PLC_LME 5086
+mspx MACH_MSPX MSPX 5087
+cgw_300 MACH_CGW_300 CGW_300 5088
+mx7d_cicada MACH_MX7D_CICADA MX7D_CICADA 5089
+virt2real_dm365 MACH_VIRT2REAL_DM365 VIRT2REAL_DM365 5090
+dm365_virt2real MACH_DM365_VIRT2REAL DM365_VIRT2REAL 5091
+h6073 MACH_H6073 H6073 5092
+gtgateway MACH_GTGATEWAY GTGATEWAY 5093
+xarina_standard MACH_XARINA_STANDARD XARINA_STANDARD 5094
+novasoms MACH_NOVASOMS NOVASOMS 5095
+novasomp MACH_NOVASOMP NOVASOMP 5096
+novasomu MACH_NOVASOMU NOVASOMU 5097
+mx6q_mpbd MACH_MX6Q_MPBD MX6Q_MPBD 5098
+ncr_1930 MACH_NCR_1930 NCR_1930 5099
+uap301 MACH_UAP301 UAP301 5100
+urt02 MACH_URT02 URT02 5101
+atc8 MACH_ATC8 ATC8 5102
+iot_gateway MACH_IOT_GATEWAY IOT_GATEWAY 5103
+hsm_phoenix MACH_HSM_PHOENIX HSM_PHOENIX 5104
+missouri MACH_MISSOURI MISSOURI 5105
+remarkable MACH_REMARKABLE REMARKABLE 5106
+fa0113 MACH_FA0113 FA0113 5107
+innova_statnettawm MACH_INNOVA_STATNETTAWM INNOVA_STATNETTAWM 5108
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
new file mode 100644
index 000000000000..3c2cb5d5adfa
--- /dev/null
+++ b/arch/arm/tools/syscall.tbl
@@ -0,0 +1,413 @@
+#
+# Linux system call numbers and entry vectors
+#
+# The format is:
+# <num> <abi> <name> [<entry point> [<oabi compat entry point>]]
+#
+# Where abi is:
+# common - for system calls shared between oabi and eabi (may have compat)
+# oabi - for oabi-only system calls (may have compat)
+# eabi - for eabi-only system calls
+#
+# For each syscall number, "common" is mutually exclusive with oabi and eabi
+#
+0 common restart_syscall sys_restart_syscall
+1 common exit sys_exit
+2 common fork sys_fork
+3 common read sys_read
+4 common write sys_write
+5 common open sys_open
+6 common close sys_close
+# 7 was sys_waitpid
+8 common creat sys_creat
+9 common link sys_link
+10 common unlink sys_unlink
+11 common execve sys_execve
+12 common chdir sys_chdir
+13 oabi time sys_time
+14 common mknod sys_mknod
+15 common chmod sys_chmod
+16 common lchown sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19 common lseek sys_lseek
+20 common getpid sys_getpid
+21 common mount sys_mount
+22 oabi umount sys_oldumount
+23 common setuid sys_setuid16
+24 common getuid sys_getuid16
+25 oabi stime sys_stime
+26 common ptrace sys_ptrace
+27 oabi alarm sys_alarm
+# 28 was sys_fstat
+29 common pause sys_pause
+30 oabi utime sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33 common access sys_access
+34 common nice sys_nice
+# 35 was sys_ftime
+36 common sync sys_sync
+37 common kill sys_kill
+38 common rename sys_rename
+39 common mkdir sys_mkdir
+40 common rmdir sys_rmdir
+41 common dup sys_dup
+42 common pipe sys_pipe
+43 common times sys_times
+# 44 was sys_prof
+45 common brk sys_brk
+46 common setgid sys_setgid16
+47 common getgid sys_getgid16
+# 48 was sys_signal
+49 common geteuid sys_geteuid16
+50 common getegid sys_getegid16
+51 common acct sys_acct
+52 common umount2 sys_umount
+# 53 was sys_lock
+54 common ioctl sys_ioctl
+55 common fcntl sys_fcntl
+# 56 was sys_mpx
+57 common setpgid sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60 common umask sys_umask
+61 common chroot sys_chroot
+62 common ustat sys_ustat
+63 common dup2 sys_dup2
+64 common getppid sys_getppid
+65 common getpgrp sys_getpgrp
+66 common setsid sys_setsid
+67 common sigaction sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70 common setreuid sys_setreuid16
+71 common setregid sys_setregid16
+72 common sigsuspend sys_sigsuspend
+73 common sigpending sys_sigpending
+74 common sethostname sys_sethostname
+75 common setrlimit sys_setrlimit
+# Back compat 2GB limited rlimit
+76 oabi getrlimit sys_old_getrlimit
+77 common getrusage sys_getrusage
+78 common gettimeofday sys_gettimeofday
+79 common settimeofday sys_settimeofday
+80 common getgroups sys_getgroups16
+81 common setgroups sys_setgroups16
+82 oabi select sys_old_select
+83 common symlink sys_symlink
+# 84 was sys_lstat
+85 common readlink sys_readlink
+86 common uselib sys_uselib
+87 common swapon sys_swapon
+88 common reboot sys_reboot
+89 oabi readdir sys_old_readdir
+90 oabi mmap sys_old_mmap
+91 common munmap sys_munmap
+92 common truncate sys_truncate
+93 common ftruncate sys_ftruncate
+94 common fchmod sys_fchmod
+95 common fchown sys_fchown16
+96 common getpriority sys_getpriority
+97 common setpriority sys_setpriority
+# 98 was sys_profil
+99 common statfs sys_statfs
+100 common fstatfs sys_fstatfs
+# 101 was sys_ioperm
+102 oabi socketcall sys_socketcall sys_oabi_socketcall
+103 common syslog sys_syslog
+104 common setitimer sys_setitimer
+105 common getitimer sys_getitimer
+106 common stat sys_newstat
+107 common lstat sys_newlstat
+108 common fstat sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111 common vhangup sys_vhangup
+# 112 was sys_idle
+# syscall to call a syscall!
+113 oabi syscall sys_syscall
+114 common wait4 sys_wait4
+115 common swapoff sys_swapoff
+116 common sysinfo sys_sysinfo
+117 oabi ipc sys_ipc sys_oabi_ipc
+118 common fsync sys_fsync
+119 common sigreturn sys_sigreturn_wrapper
+120 common clone sys_clone
+121 common setdomainname sys_setdomainname
+122 common uname sys_newuname
+# 123 was sys_modify_ldt
+124 common adjtimex sys_adjtimex
+125 common mprotect sys_mprotect
+126 common sigprocmask sys_sigprocmask
+# 127 was sys_create_module
+128 common init_module sys_init_module
+129 common delete_module sys_delete_module
+# 130 was sys_get_kernel_syms
+131 common quotactl sys_quotactl
+132 common getpgid sys_getpgid
+133 common fchdir sys_fchdir
+134 common bdflush sys_bdflush
+135 common sysfs sys_sysfs
+136 common personality sys_personality
+# 137 was sys_afs_syscall
+138 common setfsuid sys_setfsuid16
+139 common setfsgid sys_setfsgid16
+140 common _llseek sys_llseek
+141 common getdents sys_getdents
+142 common _newselect sys_select
+143 common flock sys_flock
+144 common msync sys_msync
+145 common readv sys_readv
+146 common writev sys_writev
+147 common getsid sys_getsid
+148 common fdatasync sys_fdatasync
+149 common _sysctl sys_sysctl
+150 common mlock sys_mlock
+151 common munlock sys_munlock
+152 common mlockall sys_mlockall
+153 common munlockall sys_munlockall
+154 common sched_setparam sys_sched_setparam
+155 common sched_getparam sys_sched_getparam
+156 common sched_setscheduler sys_sched_setscheduler
+157 common sched_getscheduler sys_sched_getscheduler
+158 common sched_yield sys_sched_yield
+159 common sched_get_priority_max sys_sched_get_priority_max
+160 common sched_get_priority_min sys_sched_get_priority_min
+161 common sched_rr_get_interval sys_sched_rr_get_interval
+162 common nanosleep sys_nanosleep
+163 common mremap sys_mremap
+164 common setresuid sys_setresuid16
+165 common getresuid sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168 common poll sys_poll
+169 common nfsservctl
+170 common setresgid sys_setresgid16
+171 common getresgid sys_getresgid16
+172 common prctl sys_prctl
+173 common rt_sigreturn sys_rt_sigreturn_wrapper
+174 common rt_sigaction sys_rt_sigaction
+175 common rt_sigprocmask sys_rt_sigprocmask
+176 common rt_sigpending sys_rt_sigpending
+177 common rt_sigtimedwait sys_rt_sigtimedwait
+178 common rt_sigqueueinfo sys_rt_sigqueueinfo
+179 common rt_sigsuspend sys_rt_sigsuspend
+180 common pread64 sys_pread64 sys_oabi_pread64
+181 common pwrite64 sys_pwrite64 sys_oabi_pwrite64
+182 common chown sys_chown16
+183 common getcwd sys_getcwd
+184 common capget sys_capget
+185 common capset sys_capset
+186 common sigaltstack sys_sigaltstack
+187 common sendfile sys_sendfile
+# 188 reserved
+# 189 reserved
+190 common vfork sys_vfork
+# SuS compliant getrlimit
+191 common ugetrlimit sys_getrlimit
+192 common mmap2 sys_mmap2
+193 common truncate64 sys_truncate64 sys_oabi_truncate64
+194 common ftruncate64 sys_ftruncate64 sys_oabi_ftruncate64
+195 common stat64 sys_stat64 sys_oabi_stat64
+196 common lstat64 sys_lstat64 sys_oabi_lstat64
+197 common fstat64 sys_fstat64 sys_oabi_fstat64
+198 common lchown32 sys_lchown
+199 common getuid32 sys_getuid
+200 common getgid32 sys_getgid
+201 common geteuid32 sys_geteuid
+202 common getegid32 sys_getegid
+203 common setreuid32 sys_setreuid
+204 common setregid32 sys_setregid
+205 common getgroups32 sys_getgroups
+206 common setgroups32 sys_setgroups
+207 common fchown32 sys_fchown
+208 common setresuid32 sys_setresuid
+209 common getresuid32 sys_getresuid
+210 common setresgid32 sys_setresgid
+211 common getresgid32 sys_getresgid
+212 common chown32 sys_chown
+213 common setuid32 sys_setuid
+214 common setgid32 sys_setgid
+215 common setfsuid32 sys_setfsuid
+216 common setfsgid32 sys_setfsgid
+217 common getdents64 sys_getdents64
+218 common pivot_root sys_pivot_root
+219 common mincore sys_mincore
+220 common madvise sys_madvise
+221 common fcntl64 sys_fcntl64 sys_oabi_fcntl64
+# 222 for tux
+# 223 is unused
+224 common gettid sys_gettid
+225 common readahead sys_readahead sys_oabi_readahead
+226 common setxattr sys_setxattr
+227 common lsetxattr sys_lsetxattr
+228 common fsetxattr sys_fsetxattr
+229 common getxattr sys_getxattr
+230 common lgetxattr sys_lgetxattr
+231 common fgetxattr sys_fgetxattr
+232 common listxattr sys_listxattr
+233 common llistxattr sys_llistxattr
+234 common flistxattr sys_flistxattr
+235 common removexattr sys_removexattr
+236 common lremovexattr sys_lremovexattr
+237 common fremovexattr sys_fremovexattr
+238 common tkill sys_tkill
+239 common sendfile64 sys_sendfile64
+240 common futex sys_futex
+241 common sched_setaffinity sys_sched_setaffinity
+242 common sched_getaffinity sys_sched_getaffinity
+243 common io_setup sys_io_setup
+244 common io_destroy sys_io_destroy
+245 common io_getevents sys_io_getevents
+246 common io_submit sys_io_submit
+247 common io_cancel sys_io_cancel
+248 common exit_group sys_exit_group
+249 common lookup_dcookie sys_lookup_dcookie
+250 common epoll_create sys_epoll_create
+251 common epoll_ctl sys_epoll_ctl sys_oabi_epoll_ctl
+252 common epoll_wait sys_epoll_wait sys_oabi_epoll_wait
+253 common remap_file_pages sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256 common set_tid_address sys_set_tid_address
+257 common timer_create sys_timer_create
+258 common timer_settime sys_timer_settime
+259 common timer_gettime sys_timer_gettime
+260 common timer_getoverrun sys_timer_getoverrun
+261 common timer_delete sys_timer_delete
+262 common clock_settime sys_clock_settime
+263 common clock_gettime sys_clock_gettime
+264 common clock_getres sys_clock_getres
+265 common clock_nanosleep sys_clock_nanosleep
+266 common statfs64 sys_statfs64_wrapper
+267 common fstatfs64 sys_fstatfs64_wrapper
+268 common tgkill sys_tgkill
+269 common utimes sys_utimes
+270 common arm_fadvise64_64 sys_arm_fadvise64_64
+271 common pciconfig_iobase sys_pciconfig_iobase
+272 common pciconfig_read sys_pciconfig_read
+273 common pciconfig_write sys_pciconfig_write
+274 common mq_open sys_mq_open
+275 common mq_unlink sys_mq_unlink
+276 common mq_timedsend sys_mq_timedsend
+277 common mq_timedreceive sys_mq_timedreceive
+278 common mq_notify sys_mq_notify
+279 common mq_getsetattr sys_mq_getsetattr
+280 common waitid sys_waitid
+281 common socket sys_socket
+282 common bind sys_bind sys_oabi_bind
+283 common connect sys_connect sys_oabi_connect
+284 common listen sys_listen
+285 common accept sys_accept
+286 common getsockname sys_getsockname
+287 common getpeername sys_getpeername
+288 common socketpair sys_socketpair
+289 common send sys_send
+290 common sendto sys_sendto sys_oabi_sendto
+291 common recv sys_recv
+292 common recvfrom sys_recvfrom
+293 common shutdown sys_shutdown
+294 common setsockopt sys_setsockopt
+295 common getsockopt sys_getsockopt
+296 common sendmsg sys_sendmsg sys_oabi_sendmsg
+297 common recvmsg sys_recvmsg
+298 common semop sys_semop sys_oabi_semop
+299 common semget sys_semget
+300 common semctl sys_semctl
+301 common msgsnd sys_msgsnd
+302 common msgrcv sys_msgrcv
+303 common msgget sys_msgget
+304 common msgctl sys_msgctl
+305 common shmat sys_shmat
+306 common shmdt sys_shmdt
+307 common shmget sys_shmget
+308 common shmctl sys_shmctl
+309 common add_key sys_add_key
+310 common request_key sys_request_key
+311 common keyctl sys_keyctl
+312 common semtimedop sys_semtimedop sys_oabi_semtimedop
+313 common vserver
+314 common ioprio_set sys_ioprio_set
+315 common ioprio_get sys_ioprio_get
+316 common inotify_init sys_inotify_init
+317 common inotify_add_watch sys_inotify_add_watch
+318 common inotify_rm_watch sys_inotify_rm_watch
+319 common mbind sys_mbind
+320 common get_mempolicy sys_get_mempolicy
+321 common set_mempolicy sys_set_mempolicy
+322 common openat sys_openat
+323 common mkdirat sys_mkdirat
+324 common mknodat sys_mknodat
+325 common fchownat sys_fchownat
+326 common futimesat sys_futimesat
+327 common fstatat64 sys_fstatat64 sys_oabi_fstatat64
+328 common unlinkat sys_unlinkat
+329 common renameat sys_renameat
+330 common linkat sys_linkat
+331 common symlinkat sys_symlinkat
+332 common readlinkat sys_readlinkat
+333 common fchmodat sys_fchmodat
+334 common faccessat sys_faccessat
+335 common pselect6 sys_pselect6
+336 common ppoll sys_ppoll
+337 common unshare sys_unshare
+338 common set_robust_list sys_set_robust_list
+339 common get_robust_list sys_get_robust_list
+340 common splice sys_splice
+341 common arm_sync_file_range sys_sync_file_range2
+342 common tee sys_tee
+343 common vmsplice sys_vmsplice
+344 common move_pages sys_move_pages
+345 common getcpu sys_getcpu
+346 common epoll_pwait sys_epoll_pwait
+347 common kexec_load sys_kexec_load
+348 common utimensat sys_utimensat
+349 common signalfd sys_signalfd
+350 common timerfd_create sys_timerfd_create
+351 common eventfd sys_eventfd
+352 common fallocate sys_fallocate
+353 common timerfd_settime sys_timerfd_settime
+354 common timerfd_gettime sys_timerfd_gettime
+355 common signalfd4 sys_signalfd4
+356 common eventfd2 sys_eventfd2
+357 common epoll_create1 sys_epoll_create1
+358 common dup3 sys_dup3
+359 common pipe2 sys_pipe2
+360 common inotify_init1 sys_inotify_init1
+361 common preadv sys_preadv
+362 common pwritev sys_pwritev
+363 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
+364 common perf_event_open sys_perf_event_open
+365 common recvmmsg sys_recvmmsg
+366 common accept4 sys_accept4
+367 common fanotify_init sys_fanotify_init
+368 common fanotify_mark sys_fanotify_mark
+369 common prlimit64 sys_prlimit64
+370 common name_to_handle_at sys_name_to_handle_at
+371 common open_by_handle_at sys_open_by_handle_at
+372 common clock_adjtime sys_clock_adjtime
+373 common syncfs sys_syncfs
+374 common sendmmsg sys_sendmmsg
+375 common setns sys_setns
+376 common process_vm_readv sys_process_vm_readv
+377 common process_vm_writev sys_process_vm_writev
+378 common kcmp sys_kcmp
+379 common finit_module sys_finit_module
+380 common sched_setattr sys_sched_setattr
+381 common sched_getattr sys_sched_getattr
+382 common renameat2 sys_renameat2
+383 common seccomp sys_seccomp
+384 common getrandom sys_getrandom
+385 common memfd_create sys_memfd_create
+386 common bpf sys_bpf
+387 common execveat sys_execveat
+388 common userfaultfd sys_userfaultfd
+389 common membarrier sys_membarrier
+390 common mlock2 sys_mlock2
+391 common copy_file_range sys_copy_file_range
+392 common preadv2 sys_preadv2
+393 common pwritev2 sys_pwritev2
+394 common pkey_mprotect sys_pkey_mprotect
+395 common pkey_alloc sys_pkey_alloc
+396 common pkey_free sys_pkey_free
diff --git a/arch/arm/tools/syscallhdr.sh b/arch/arm/tools/syscallhdr.sh
new file mode 100644
index 000000000000..72d4b2e3bdec
--- /dev/null
+++ b/arch/arm/tools/syscallhdr.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+in="$1"
+out="$2"
+my_abis=`echo "($3)" | tr ',' '|'`
+prefix="$4"
+offset="$5"
+
+fileguard=_ASM_ARM_`basename "$out" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+ -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
+if echo $out | grep -q uapi; then
+ fileguard="_UAPI$fileguard"
+fi
+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
+ echo "#ifndef ${fileguard}"
+ echo "#define ${fileguard} 1"
+ echo ""
+
+ while read nr abi name entry ; do
+ if [ -z "$offset" ]; then
+ echo "#define __NR_${prefix}${name} $nr"
+ else
+ echo "#define __NR_${prefix}${name} ($offset + $nr)"
+ fi
+ done
+
+ echo ""
+ echo "#endif /* ${fileguard} */"
+) > "$out"
diff --git a/arch/arm/tools/syscallnr.sh b/arch/arm/tools/syscallnr.sh
new file mode 100644
index 000000000000..d2971296469a
--- /dev/null
+++ b/arch/arm/tools/syscallnr.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+in="$1"
+out="$2"
+my_abis=`echo "($3)" | tr ',' '|'`
+align=1
+
+fileguard=_ASM_ARM_`basename "$out" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+ -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
+
+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | tail -n1 | (
+ echo "#ifndef ${fileguard}
+#define ${fileguard} 1
+
+/*
+ * This needs to be greater than __NR_last_syscall+1 in order to account
+ * for the padding in the syscall table.
+ */
+"
+
+ while read nr abi name entry; do
+ nr=$(($nr + 1))
+ while [ "$(($nr / (256 * $align) ))" -gt 0 ]; do
+ align=$(( $align * 4 ))
+ done
+ nr=$(( ($nr + $align - 1) & ~($align - 1) ))
+ echo "/* aligned to $align */"
+ echo "#define __NR_syscalls $nr"
+ done
+
+ echo ""
+ echo "#endif /* ${fileguard} */"
+) > "$out"
diff --git a/arch/arm/tools/syscalltbl.sh b/arch/arm/tools/syscalltbl.sh
new file mode 100644
index 000000000000..5ca834545ed3
--- /dev/null
+++ b/arch/arm/tools/syscalltbl.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+in="$1"
+out="$2"
+my_abis=`echo "($3)" | tr ',' '|'`
+
+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
+ while read nr abi name entry compat; do
+ if [ "$abi" = "eabi" -a -n "$compat" ]; then
+ echo "$in: error: a compat entry for an EABI syscall ($name) makes no sense" >&2
+ exit 1
+ fi
+
+ if [ -n "$entry" ]; then
+ if [ -z "$compat" ]; then
+ echo "NATIVE($nr, $entry)"
+ else
+ echo "COMPAT($nr, $entry, $compat)"
+ fi
+ fi
+ done
+) > "$out"
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index c8c98dd44ad4..89773e5ddf35 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -155,8 +155,8 @@ struct vfp_single {
u32 significand;
};
-extern s32 vfp_get_float(unsigned int reg);
-extern void vfp_put_float(s32 val, unsigned int reg);
+asmlinkage s32 vfp_get_float(unsigned int reg);
+asmlinkage void vfp_put_float(s32 val, unsigned int reg);
/*
* VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa
@@ -270,8 +270,8 @@ struct vfp_double {
#else
#define VFP_REG_ZERO 16
#endif
-extern u64 vfp_get_double(unsigned int reg);
-extern void vfp_put_double(u64 val, unsigned int reg);
+asmlinkage u64 vfp_get_double(unsigned int reg);
+asmlinkage void vfp_put_double(u64 val, unsigned int reg);
#define VFP_DOUBLE_MANTISSA_BITS (52)
#define VFP_DOUBLE_EXPONENT_BITS (11)
@@ -377,4 +377,4 @@ struct op {
u32 flags;
};
-extern void vfp_save_state(void *location, u32 fpexc);
+asmlinkage void vfp_save_state(void *location, u32 fpexc);
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index da0b33deba6d..0351f5645fb1 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -34,11 +34,11 @@
/*
* Our undef handlers (in entry.S)
*/
-void vfp_testing_entry(void);
-void vfp_support_entry(void);
-void vfp_null_entry(void);
+asmlinkage void vfp_testing_entry(void);
+asmlinkage void vfp_support_entry(void);
+asmlinkage void vfp_null_entry(void);
-void (*vfp_vector)(void) = vfp_null_entry;
+asmlinkage void (*vfp_vector)(void) = vfp_null_entry;
/*
* Dual-use variable.
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 101794f5ce10..715ef1256838 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -113,6 +113,7 @@ config ARCH_MVEBU
config ARCH_QCOM
bool "Qualcomm Platforms"
+ select GPIOLIB
select PINCTRL
help
This enables support for the ARMv8 based Qualcomm chipsets.
@@ -143,6 +144,7 @@ config ARCH_RENESAS
select PM
select PM_GENERIC_DOMAINS
select RENESAS_IRQC
+ select SOC_BUS
help
This enables support for the ARMv8 based Renesas SoCs.
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 6684f97c2722..080232b0270e 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,4 +1,5 @@
dts-dirs += al
+dts-dirs += allwinner
dts-dirs += altera
dts-dirs += amd
dts-dirs += amlogic
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
new file mode 100644
index 000000000000..1e29a5ae8282
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
+
+always := $(dtb-y)
+subdir-y := $(dts-dirs)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
new file mode 100644
index 000000000000..790d14daaa6a
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 ARM 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 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.
+ */
+
+#include "sun50i-a64-pine64.dts"
+
+/ {
+ model = "Pine64+";
+ compatible = "pine64,pine64-plus", "allwinner,sun50i-a64";
+
+ /* TODO: Camera, Ethernet PHY, touchscreen, etc. */
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
new file mode 100644
index 000000000000..47095909d9d6
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 ARM 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 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 "sun50i-a64.dtsi"
+
+/ {
+ model = "Pine64";
+ compatible = "pine64,pine64", "allwinner,sun50i-a64";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ status = "okay";
+};
+
+&i2c1_pins {
+ bias-pull-up;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
new file mode 100644
index 000000000000..e0dcab8eb035
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2016 ARM Ltd.
+ * based on the Allwinner H3 dtsi:
+ * 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <0>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <1>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <2>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ reg = <3>;
+ enable-method = "psci";
+ };
+ };
+
+ 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";
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ 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)>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ ccu: clock@01c20000 {
+ compatible = "allwinner,sun50i-a64-ccu";
+ reg = <0x01c20000 0x400>;
+ clocks = <&osc24M>, <&osc32k>;
+ clock-names = "hosc", "losc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ pio: pinctrl@1c20800 {
+ compatible = "allwinner,sun50i-a64-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu 58>;
+ gpio-controller;
+ #gpio-cells = <3>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+
+ i2c1_pins: i2c1_pins {
+ pins = "PH2", "PH3";
+ function = "i2c1";
+ };
+
+ uart0_pins_a: uart0@0 {
+ pins = "PB8", "PB9";
+ function = "uart0";
+ };
+ };
+
+ uart0: serial@1c28000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28000 0x400>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&ccu 67>;
+ resets = <&ccu 46>;
+ status = "disabled";
+ };
+
+ uart1: serial@1c28400 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28400 0x400>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&ccu 68>;
+ resets = <&ccu 47>;
+ status = "disabled";
+ };
+
+ uart2: serial@1c28800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28800 0x400>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&ccu 69>;
+ resets = <&ccu 48>;
+ status = "disabled";
+ };
+
+ uart3: serial@1c28c00 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c28c00 0x400>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&ccu 70>;
+ resets = <&ccu 49>;
+ status = "disabled";
+ };
+
+ uart4: serial@1c29000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01c29000 0x400>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&ccu 71>;
+ resets = <&ccu 50>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@1c2ac00 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu 63>;
+ resets = <&ccu 42>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: i2c@1c2b000 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu 64>;
+ resets = <&ccu 43>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2: i2c@1c2b400 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu 65>;
+ resets = <&ccu 44>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ gic: interrupt-controller@1c81000 {
+ compatible = "arm,gic-400";
+ reg = <0x01c81000 0x1000>,
+ <0x01c82000 0x2000>,
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ rtc: rtc@1f00000 {
+ compatible = "allwinner,sun6i-a31-rtc";
+ reg = <0x01f00000 0x54>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 47ec703cb230..0d7bfbf7d922 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -1,9 +1,17 @@
+dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-p200.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-p201.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-meta.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-telos.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-nexbox-a95x.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-q200.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-q201.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
new file mode 100644
index 000000000000..7a078bef04cd
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+/* Common DTSI for same Amlogic Q200/Q201 and P230/P231 boards using either
+ * the pin-compatible S912 (GXM) or S905D (GXL) SoCs.
+ */
+
+/ {
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+};
+
+/* This UART is brought out to the DB9 connector */
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&clkc CLKID_FCLK_DIV4>;
+ clock-names = "clkin0";
+};
+
+&ethmac {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
new file mode 100644
index 000000000000..fc033c0d2a0f
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ l2: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
+
+ firmware {
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gx-sm", "amlogic,meson-gxbb-sm";
+ };
+ };
+
+ efuse: efuse {
+ compatible = "amlogic,meson-gx-efuse", "amlogic,meson-gxbb-efuse";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sn: sn@14 {
+ reg = <0x14 0x10>;
+ };
+
+ eth_mac: eth_mac@34 {
+ reg = <0x34 0x10>;
+ };
+
+ bid: bid@46 {
+ reg = <0x46 0x30>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ cbus: cbus@c1100000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc1100000 0x0 0x100000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>;
+
+ reset: reset-controller@4404 {
+ compatible = "amlogic,meson-gx-reset", "amlogic,meson-gxbb-reset";
+ reg = <0x0 0x04404 0x0 0x20>;
+ #reset-cells = <1>;
+ };
+
+ uart_A: serial@84c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x84c0 0x0 0x14>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ uart_B: serial@84dc {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x84dc 0x0 0x14>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ i2c_A: i2c@8500 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x08500 0x0 0x20>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pwm_ab: pwm@8550 {
+ compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x08550 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_cd: pwm@8650 {
+ compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x08650 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_ef: pwm@86c0 {
+ compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x086c0 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ uart_C: serial@8700 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x8700 0x0 0x14>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ i2c_B: i2c@87c0 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x087c0 0x0 0x20>;
+ interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c_C: i2c@87e0 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x087e0 0x0 0x20>;
+ interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ watchdog@98d0 {
+ compatible = "amlogic,meson-gx-wdt", "amlogic,meson-gxbb-wdt";
+ reg = <0x0 0x098d0 0x0 0x10>;
+ clocks = <&xtal>;
+ };
+ };
+
+ gic: interrupt-controller@c4301000 {
+ compatible = "arm,gic-400";
+ reg = <0x0 0xc4301000 0 0x1000>,
+ <0x0 0xc4302000 0 0x2000>,
+ <0x0 0xc4304000 0 0x2000>,
+ <0x0 0xc4306000 0 0x2000>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ };
+
+ aobus: aobus@c8100000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc8100000 0x0 0x100000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
+
+ uart_AO: serial@4c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x0 0x004c0 0x0 0x14>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>;
+ status = "disabled";
+ };
+
+ ir: ir@580 {
+ compatible = "amlogic,meson-gxbb-ir";
+ reg = <0x0 0x00580 0x0 0x40>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+ };
+
+ periphs: periphs@c8834000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc8834000 0x0 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
+
+ rng {
+ compatible = "amlogic,meson-rng";
+ reg = <0x0 0x0 0x0 0x4>;
+ };
+ };
+
+
+ hiubus: hiubus@c883c000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xc883c000 0x0 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
+
+ mailbox: mailbox@404 {
+ compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+ reg = <0 0x404 0 0x4c>;
+ interrupts = <0 208 IRQ_TYPE_EDGE_RISING>,
+ <0 209 IRQ_TYPE_EDGE_RISING>,
+ <0 210 IRQ_TYPE_EDGE_RISING>;
+ #mbox-cells = <1>;
+ };
+ };
+
+ ethmac: ethernet@c9410000 {
+ compatible = "amlogic,meson-gx-dwmac", "amlogic,meson-gxbb-dwmac", "snps,dwmac";
+ reg = <0x0 0xc9410000 0x0 0x10000
+ 0x0 0xc8834540 0x0 0x4>;
+ interrupts = <0 8 1>;
+ interrupt-names = "macirq";
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
+ apb: apb@d0000000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xd0000000 0x0 0x200000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>;
+
+ sd_emmc_a: mmc@70000 {
+ compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
+ reg = <0x0 0x70000 0x0 0x2000>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ sd_emmc_b: mmc@72000 {
+ compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
+ reg = <0x0 0x72000 0x0 0x2000>;
+ interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ sd_emmc_c: mmc@74000 {
+ compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
+ reg = <0x0 0x74000 0x0 0x2000>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
new file mode 100644
index 000000000000..969682092e0f
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Author: Neil Armstrong <narmstrong@kernel.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
+ * 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 "meson-gxbb.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ compatible = "nexbox,a95x", "amlogic,meson-gxbb";
+ model = "NEXBOX A95X";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ blue {
+ label = "a95x:system-status";
+ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <100>;
+
+ button@0 {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ vddio_card: gpio-regulator {
+ compatible = "regulator-gpio";
+
+ regulator-name = "VDDIO_CARD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+
+ /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
+ states = <1800000 0
+ 3300000 1>;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&ethmac {
+ status = "okay";
+ pinctrl-0 = <&eth_rmii_pins>;
+ pinctrl-names = "default";
+ phy-mode = "rmii";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_card>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&clkc CLKID_FCLK_DIV4>;
+ clock-names = "clkin0";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index e6e3491d48a5..238fbeacd330 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -64,6 +64,18 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
+ usb_otg_pwr: regulator-usb-pwrs {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB_OTG_PWR";
+
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
leds {
compatible = "gpio-leds";
blue {
@@ -73,6 +85,56 @@
default-state = "off";
};
};
+
+ tflash_vdd: regulator-tflash_vdd {
+ /*
+ * signal name from schematics: TFLASH_VDD_EN
+ */
+ compatible = "regulator-fixed";
+
+ regulator-name = "TFLASH_VDD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio_ao GPIOAO_12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ tf_io: gpio-regulator-tf_io {
+ compatible = "regulator-gpio";
+
+ regulator-name = "TF_IO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ /*
+ * signal name from schematics: TF_3V3N_1V8_EN
+ */
+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+ gpios-states = <0>;
+
+ states = <3300000 0
+ 1800000 1>;
+ };
+
+ vcc1v8: regulator-vcc1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc3v3: regulator-vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
};
&uart_AO {
@@ -83,7 +145,7 @@
&ethmac {
status = "okay";
- pinctrl-0 = <&eth_pins>;
+ pinctrl-0 = <&eth_rgmii_pins>;
pinctrl-names = "default";
};
@@ -98,3 +160,58 @@
pinctrl-0 = <&i2c_a_pins>;
pinctrl-names = "default";
};
+
+&usb0_phy {
+ status = "okay";
+ phy-supply = <&usb_otg_pwr>;
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
+
+/* SD */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&tflash_vdd>;
+ vqmmc-supply = <&tf_io>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc3v3>;
+ vqmmc-supply = <&vcc1v8>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 06a34dc6002f..203be28978d5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -70,6 +70,61 @@
gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ vddio_card: gpio-regulator {
+ compatible = "regulator-gpio";
+
+ regulator-name = "VDDIO_CARD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+
+ /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
+ states = <1800000 0
+ 3300000 1>;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
};
/* This UART is brought out to the DB9 connector */
@@ -81,7 +136,7 @@
&ethmac {
status = "okay";
- pinctrl-0 = <&eth_pins>;
+ pinctrl-0 = <&eth_rgmii_pins>;
pinctrl-names = "default";
};
@@ -107,3 +162,75 @@
&usb1 {
status = "okay";
};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_card>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&clkc CLKID_FCLK_DIV4>;
+ clock-names = "clkin0";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 73f159370188..e59ad308192f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -65,6 +65,39 @@
enable-active-high;
};
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_1v8: regulator-vcc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>,
+ <&gpio GPIOX_20 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
};
&uart_AO {
@@ -82,7 +115,7 @@
&ethmac {
status = "okay";
- pinctrl-0 = <&eth_pins>;
+ pinctrl-0 = <&eth_rgmii_pins>;
pinctrl-names = "default";
};
@@ -102,3 +135,74 @@
&usb1 {
status = "okay";
};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins &sdio_irq_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vcc_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vmmcq-sumpply = <&vcc_1v8>;
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&clkc CLKID_FCLK_DIV4>;
+ clock-names = "clkin0";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 610e0e1c3cee..51edd5b5c460 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -40,9 +40,7 @@
* 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 "meson-gx.dtsi"
#include <dt-bindings/gpio/meson-gxbb-gpio.h>
#include <dt-bindings/reset/amlogic,meson-gxbb-reset.h>
#include <dt-bindings/clock/gxbb-clkc.h>
@@ -51,106 +49,30 @@
/ {
compatible = "amlogic,meson-gxbb";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
- cpus {
- #address-cells = <0x2>;
- #size-cells = <0x0>;
+ scpi {
+ compatible = "amlogic,meson-gxbb-scpi", "arm,scpi-pre-1.0";
+ mboxes = <&mailbox 1 &mailbox 2>;
+ shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
- cpu0: cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x0>;
- enable-method = "psci";
- };
-
- cpu1: cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x1>;
- enable-method = "psci";
- };
-
- cpu2: cpu@2 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x2>;
- enable-method = "psci";
- };
-
- cpu3: cpu@3 {
- device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
- reg = <0x0 0x3>;
- enable-method = "psci";
- };
- };
-
- arm-pmu {
- compatible = "arm,cortex-a53-pmu";
- interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
- };
+ clocks {
+ compatible = "arm,scpi-clocks";
- psci {
- compatible = "arm,psci-0.2";
- method = "smc";
- };
-
- firmware {
- sm: secure-monitor {
- compatible = "amlogic,meson-gxbb-sm";
- };
- };
-
- efuse: efuse {
- compatible = "amlogic,meson-gxbb-efuse";
- #address-cells = <1>;
- #size-cells = <1>;
-
- sn: sn@14 {
- reg = <0x14 0x10>;
- };
-
- eth_mac: eth_mac@34 {
- reg = <0x34 0x10>;
+ scpi_dvfs: scpi_clocks@0 {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>;
+ clock-output-names = "vcpu";
+ };
};
- bid: bid@46 {
- reg = <0x46 0x30>;
+ scpi_sensors: sensors {
+ compatible = "arm,scpi-sensors";
+ #thermal-sensor-cells = <1>;
};
};
- timer {
- compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 13
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10
- (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
- };
-
- xtal: xtal-clk {
- compatible = "fixed-clock";
- clock-frequency = <24000000>;
- clock-output-names = "xtal";
- #clock-cells = <0>;
- };
-
soc {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
usb0_phy: phy@c0000000 {
compatible = "amlogic,meson-gxbb-usb2-phy";
#phy-cells = <0>;
@@ -165,505 +87,422 @@
compatible = "amlogic,meson-gxbb-usb2-phy";
#phy-cells = <0>;
reg = <0x0 0xc0000020 0x0 0x20>;
+ resets = <&reset RESET_USB_OTG>;
clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>;
clock-names = "usb_general", "usb";
status = "disabled";
};
- cbus: cbus@c1100000 {
- compatible = "simple-bus";
- reg = <0x0 0xc1100000 0x0 0x100000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>;
+ sram: sram@c8000000 {
+ compatible = "amlogic,meson-gxbb-sram", "mmio-sram";
+ reg = <0x0 0xc8000000 0x0 0x14000>;
- reset: reset-controller@4404 {
- compatible = "amlogic,meson-gxbb-reset";
- reg = <0x0 0x04404 0x0 0x20>;
- #reset-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0xc8000000 0x14000>;
+
+ cpu_scp_lpri: scp-shmem@0 {
+ compatible = "amlogic,meson-gxbb-scp-shmem";
+ reg = <0x13000 0x400>;
+ };
+
+ cpu_scp_hpri: scp-shmem@200 {
+ compatible = "amlogic,meson-gxbb-scp-shmem";
+ reg = <0x13400 0x400>;
};
+ };
+
+ usb0: usb@c9000000 {
+ compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
+ reg = <0x0 0xc9000000 0x0 0x40000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_USB0_DDR_BRIDGE>;
+ clock-names = "otg";
+ phys = <&usb0_phy>;
+ phy-names = "usb2-phy";
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usb1: usb@c9100000 {
+ compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
+ reg = <0x0 0xc9100000 0x0 0x40000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_USB1_DDR_BRIDGE>;
+ clock-names = "otg";
+ phys = <&usb1_phy>;
+ phy-names = "usb2-phy";
+ dr_mode = "host";
+ status = "disabled";
+ };
+ };
+};
+
+&cpu0 {
+ clocks = <&scpi_dvfs 0>;
+};
+
+&cpu1 {
+ clocks = <&scpi_dvfs 0>;
+};
+
+&cpu2 {
+ clocks = <&scpi_dvfs 0>;
+};
+
+&cpu3 {
+ clocks = <&scpi_dvfs 0>;
+};
+
+&cbus {
+ spifc: spi@8c80 {
+ compatible = "amlogic,meson-gxbb-spifc";
+ reg = <0x0 0x08c80 0x0 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc CLKID_SPI>;
+ status = "disabled";
+ };
+};
+
+&ethmac {
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+};
+
+&aobus {
+ pinctrl_aobus: pinctrl@14 {
+ compatible = "amlogic,meson-gxbb-aobus-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio_ao: bank@14 {
+ reg = <0x0 0x00014 0x0 0x8>,
+ <0x0 0x0002c 0x0 0x4>,
+ <0x0 0x00024 0x0 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
- uart_A: serial@84c0 {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x84c0 0x0 0x14>;
- interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_tx_ao_a", "uart_rx_ao_a";
+ function = "uart_ao";
};
+ };
- uart_B: serial@84dc {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x84dc 0x0 0x14>;
- interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
+ remote_input_ao_pins: remote_input_ao {
+ mux {
+ groups = "remote_input_ao";
+ function = "remote_input_ao";
};
+ };
- pwm_ab: pwm@8550 {
- compatible = "amlogic,meson-gxbb-pwm";
- reg = <0x0 0x08550 0x0 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
+ i2c_ao_pins: i2c_ao {
+ mux {
+ groups = "i2c_sck_ao",
+ "i2c_sda_ao";
+ function = "i2c_ao";
};
+ };
- pwm_cd: pwm@8650 {
- compatible = "amlogic,meson-gxbb-pwm";
- reg = <0x0 0x08650 0x0 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
+ pwm_ao_a_3_pins: pwm_ao_a_3 {
+ mux {
+ groups = "pwm_ao_a_3";
+ function = "pwm_ao_a_3";
};
+ };
- pwm_ef: pwm@86c0 {
- compatible = "amlogic,meson-gxbb-pwm";
- reg = <0x0 0x086c0 0x0 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
+ pwm_ao_a_6_pins: pwm_ao_a_6 {
+ mux {
+ groups = "pwm_ao_a_6";
+ function = "pwm_ao_a_6";
};
+ };
- uart_C: serial@8700 {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x8700 0x0 0x14>;
- interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
+ pwm_ao_a_12_pins: pwm_ao_a_12 {
+ mux {
+ groups = "pwm_ao_a_12";
+ function = "pwm_ao_a_12";
};
+ };
- watchdog@98d0 {
- compatible = "amlogic,meson-gxbb-wdt";
- reg = <0x0 0x098d0 0x0 0x10>;
- clocks = <&xtal>;
+ pwm_ao_b_pins: pwm_ao_b {
+ mux {
+ groups = "pwm_ao_b";
+ function = "pwm_ao_b";
};
+ };
+ };
+
+ clkc_AO: clock-controller@040 {
+ compatible = "amlogic,gxbb-aoclkc";
+ reg = <0x0 0x00040 0x0 0x4>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ pwm_ab_AO: pwm@550 {
+ compatible = "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x0550 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ i2c_AO: i2c@500 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x500 0x0 0x20>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_AO_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
+
+&periphs {
+ pinctrl_periphs: pinctrl@4b0 {
+ compatible = "amlogic,meson-gxbb-periphs-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio: bank@4b0 {
+ reg = <0x0 0x004b0 0x0 0x28>,
+ <0x0 0x004e8 0x0 0x14>,
+ <0x0 0x00120 0x0 0x14>,
+ <0x0 0x00430 0x0 0x40>;
+ reg-names = "mux", "pull", "pull-enable", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
- spifc: spi@8c80 {
- compatible = "amlogic,meson-gxbb-spifc";
- reg = <0x0 0x08c80 0x0 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&clkc CLKID_SPI>;
- status = "disabled";
+ emmc_pins: emmc {
+ mux {
+ groups = "emmc_nand_d07",
+ "emmc_cmd",
+ "emmc_clk",
+ "emmc_ds";
+ function = "emmc";
};
+ };
- i2c_A: i2c@8500 {
- compatible = "amlogic,meson-gxbb-i2c";
- reg = <0x0 0x08500 0x0 0x20>;
- interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
- clocks = <&clkc CLKID_I2C>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+ nor_pins: nor {
+ mux {
+ groups = "nor_d",
+ "nor_q",
+ "nor_c",
+ "nor_cs";
+ function = "nor";
};
+ };
- i2c_B: i2c@87c0 {
- compatible = "amlogic,meson-gxbb-i2c";
- reg = <0x0 0x087c0 0x0 0x20>;
- interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
- clocks = <&clkc CLKID_I2C>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+ sdcard_pins: sdcard {
+ mux {
+ groups = "sdcard_d0",
+ "sdcard_d1",
+ "sdcard_d2",
+ "sdcard_d3",
+ "sdcard_cmd",
+ "sdcard_clk";
+ function = "sdcard";
};
+ };
- i2c_C: i2c@87e0 {
- compatible = "amlogic,meson-gxbb-i2c";
- reg = <0x0 0x087e0 0x0 0x20>;
- interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
- clocks = <&clkc CLKID_I2C>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+ sdio_pins: sdio {
+ mux {
+ groups = "sdio_d0",
+ "sdio_d1",
+ "sdio_d2",
+ "sdio_d3",
+ "sdio_cmd",
+ "sdio_clk";
+ function = "sdio";
};
};
- gic: interrupt-controller@c4301000 {
- compatible = "arm,gic-400";
- reg = <0x0 0xc4301000 0 0x1000>,
- <0x0 0xc4302000 0 0x2000>,
- <0x0 0xc4304000 0 0x2000>,
- <0x0 0xc4306000 0 0x2000>;
- interrupt-controller;
- interrupts = <GIC_PPI 9
- (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
- #interrupt-cells = <3>;
- #address-cells = <0>;
- };
-
- aobus: aobus@c8100000 {
- compatible = "simple-bus";
- reg = <0x0 0xc8100000 0x0 0x100000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
-
- pinctrl_aobus: pinctrl@14 {
- compatible = "amlogic,meson-gxbb-aobus-pinctrl";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- gpio_ao: bank@14 {
- reg = <0x0 0x00014 0x0 0x8>,
- <0x0 0x0002c 0x0 0x4>,
- <0x0 0x00024 0x0 0x8>;
- reg-names = "mux", "pull", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- uart_ao_a_pins: uart_ao_a {
- mux {
- groups = "uart_tx_ao_a", "uart_rx_ao_a";
- function = "uart_ao";
- };
- };
-
- remote_input_ao_pins: remote_input_ao {
- mux {
- groups = "remote_input_ao";
- function = "remote_input_ao";
- };
- };
-
- i2c_ao_pins: i2c_ao {
- mux {
- groups = "i2c_sck_ao",
- "i2c_sda_ao";
- function = "i2c_ao";
- };
- };
-
- pwm_ao_a_3_pins: pwm_ao_a_3 {
- mux {
- groups = "pwm_ao_a_3";
- function = "pwm_ao_a_3";
- };
- };
-
- pwm_ao_a_6_pins: pwm_ao_a_6 {
- mux {
- groups = "pwm_ao_a_6";
- function = "pwm_ao_a_6";
- };
- };
-
- pwm_ao_a_12_pins: pwm_ao_a_12 {
- mux {
- groups = "pwm_ao_a_12";
- function = "pwm_ao_a_12";
- };
- };
-
- pwm_ao_b_pins: pwm_ao_b {
- mux {
- groups = "pwm_ao_b";
- function = "pwm_ao_b";
- };
- };
+ sdio_irq_pins: sdio_irq {
+ mux {
+ groups = "sdio_irq";
+ function = "sdio";
};
+ };
- clkc_AO: clock-controller@040 {
- compatible = "amlogic,gxbb-aoclkc";
- reg = <0x0 0x00040 0x0 0x4>;
- #clock-cells = <1>;
- #reset-cells = <1>;
+ uart_a_pins: uart_a {
+ mux {
+ groups = "uart_tx_a",
+ "uart_rx_a";
+ function = "uart_a";
};
+ };
- uart_AO: serial@4c0 {
- compatible = "amlogic,meson-uart";
- reg = <0x0 0x004c0 0x0 0x14>;
- interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
- clocks = <&xtal>;
- status = "disabled";
+ uart_b_pins: uart_b {
+ mux {
+ groups = "uart_tx_b",
+ "uart_rx_b";
+ function = "uart_b";
};
+ };
- ir: ir@580 {
- compatible = "amlogic,meson-gxbb-ir";
- reg = <0x0 0x00580 0x0 0x40>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
- status = "disabled";
+ uart_c_pins: uart_c {
+ mux {
+ groups = "uart_tx_c",
+ "uart_rx_c";
+ function = "uart_c";
};
+ };
- pwm_ab_AO: pwm@550 {
- compatible = "amlogic,meson-gxbb-pwm";
- reg = <0x0 0x0550 0x0 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
+ i2c_a_pins: i2c_a {
+ mux {
+ groups = "i2c_sck_a",
+ "i2c_sda_a";
+ function = "i2c_a";
};
+ };
- i2c_AO: i2c@500 {
- compatible = "amlogic,meson-gxbb-i2c";
- reg = <0x0 0x500 0x0 0x20>;
- interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
- clocks = <&clkc CLKID_AO_I2C>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+ i2c_b_pins: i2c_b {
+ mux {
+ groups = "i2c_sck_b",
+ "i2c_sda_b";
+ function = "i2c_b";
};
};
- periphs: periphs@c8834000 {
- compatible = "simple-bus";
- reg = <0x0 0xc8834000 0x0 0x2000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
+ i2c_c_pins: i2c_c {
+ mux {
+ groups = "i2c_sck_c",
+ "i2c_sda_c";
+ function = "i2c_c";
+ };
+ };
- rng {
- compatible = "amlogic,meson-rng";
- reg = <0x0 0x0 0x0 0x4>;
+ eth_rgmii_pins: eth-rgmii {
+ mux {
+ groups = "eth_mdio",
+ "eth_mdc",
+ "eth_clk_rx_clk",
+ "eth_rx_dv",
+ "eth_rxd0",
+ "eth_rxd1",
+ "eth_rxd2",
+ "eth_rxd3",
+ "eth_rgmii_tx_clk",
+ "eth_tx_en",
+ "eth_txd0",
+ "eth_txd1",
+ "eth_txd2",
+ "eth_txd3";
+ function = "eth";
};
+ };
- pinctrl_periphs: pinctrl@4b0 {
- compatible = "amlogic,meson-gxbb-periphs-pinctrl";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- gpio: bank@4b0 {
- reg = <0x0 0x004b0 0x0 0x28>,
- <0x0 0x004e8 0x0 0x14>,
- <0x0 0x00120 0x0 0x14>,
- <0x0 0x00430 0x0 0x40>;
- reg-names = "mux", "pull", "pull-enable", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- emmc_pins: emmc {
- mux {
- groups = "emmc_nand_d07",
- "emmc_cmd",
- "emmc_clk";
- function = "emmc";
- };
- };
-
- nor_pins: nor {
- mux {
- groups = "nor_d",
- "nor_q",
- "nor_c",
- "nor_cs";
- function = "nor";
- };
- };
-
- sdcard_pins: sdcard {
- mux {
- groups = "sdcard_d0",
- "sdcard_d1",
- "sdcard_d2",
- "sdcard_d3",
- "sdcard_cmd",
- "sdcard_clk";
- function = "sdcard";
- };
- };
-
- sdio_pins: sdio {
- mux {
- groups = "sdio_d0",
- "sdio_d1",
- "sdio_d2",
- "sdio_d3",
- "sdio_cmd",
- "sdio_clk";
- function = "sdio";
- };
- };
-
- sdio_irq_pins: sdio_irq {
- mux {
- groups = "sdio_irq";
- function = "sdio";
- };
- };
-
- uart_a_pins: uart_a {
- mux {
- groups = "uart_tx_a",
- "uart_rx_a";
- function = "uart_a";
- };
- };
-
- uart_b_pins: uart_b {
- mux {
- groups = "uart_tx_b",
- "uart_rx_b";
- function = "uart_b";
- };
- };
-
- uart_c_pins: uart_c {
- mux {
- groups = "uart_tx_c",
- "uart_rx_c";
- function = "uart_c";
- };
- };
-
- i2c_a_pins: i2c_a {
- mux {
- groups = "i2c_sck_a",
- "i2c_sda_a";
- function = "i2c_a";
- };
- };
-
- i2c_b_pins: i2c_b {
- mux {
- groups = "i2c_sck_b",
- "i2c_sda_b";
- function = "i2c_b";
- };
- };
-
- i2c_c_pins: i2c_c {
- mux {
- groups = "i2c_sck_c",
- "i2c_sda_c";
- function = "i2c_c";
- };
- };
-
- eth_pins: eth_c {
- mux {
- groups = "eth_mdio",
- "eth_mdc",
- "eth_clk_rx_clk",
- "eth_rx_dv",
- "eth_rxd0",
- "eth_rxd1",
- "eth_rxd2",
- "eth_rxd3",
- "eth_rgmii_tx_clk",
- "eth_tx_en",
- "eth_txd0",
- "eth_txd1",
- "eth_txd2",
- "eth_txd3";
- function = "eth";
- };
- };
-
- pwm_a_x_pins: pwm_a_x {
- mux {
- groups = "pwm_a_x";
- function = "pwm_a_x";
- };
- };
-
- pwm_a_y_pins: pwm_a_y {
- mux {
- groups = "pwm_a_y";
- function = "pwm_a_y";
- };
- };
-
- pwm_b_pins: pwm_b {
- mux {
- groups = "pwm_b";
- function = "pwm_b";
- };
- };
-
- pwm_d_pins: pwm_d {
- mux {
- groups = "pwm_d";
- function = "pwm_d";
- };
- };
-
- pwm_e_pins: pwm_e {
- mux {
- groups = "pwm_e";
- function = "pwm_e";
- };
- };
-
- pwm_f_x_pins: pwm_f_x {
- mux {
- groups = "pwm_f_x";
- function = "pwm_f_x";
- };
- };
-
- pwm_f_y_pins: pwm_f_y {
- mux {
- groups = "pwm_f_y";
- function = "pwm_f_y";
- };
- };
+ eth_rmii_pins: eth-rmii {
+ mux {
+ groups = "eth_mdio",
+ "eth_mdc",
+ "eth_clk_rx_clk",
+ "eth_rx_dv",
+ "eth_rxd0",
+ "eth_rxd1",
+ "eth_tx_en",
+ "eth_txd0",
+ "eth_txd1";
+ function = "eth";
};
};
- hiubus: hiubus@c883c000 {
- compatible = "simple-bus";
- reg = <0x0 0xc883c000 0x0 0x2000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
+ pwm_a_x_pins: pwm_a_x {
+ mux {
+ groups = "pwm_a_x";
+ function = "pwm_a_x";
+ };
+ };
- clkc: clock-controller@0 {
- compatible = "amlogic,gxbb-clkc";
- #clock-cells = <1>;
- reg = <0x0 0x0 0x0 0x3db>;
+ pwm_a_y_pins: pwm_a_y {
+ mux {
+ groups = "pwm_a_y";
+ function = "pwm_a_y";
};
+ };
- mailbox: mailbox@404 {
- compatible = "amlogic,meson-gxbb-mhu";
- reg = <0 0x404 0 0x4c>;
- interrupts = <0 208 IRQ_TYPE_EDGE_RISING>,
- <0 209 IRQ_TYPE_EDGE_RISING>,
- <0 210 IRQ_TYPE_EDGE_RISING>;
- #mbox-cells = <1>;
+ pwm_b_pins: pwm_b {
+ mux {
+ groups = "pwm_b";
+ function = "pwm_b";
};
};
- apb: apb@d0000000 {
- compatible = "simple-bus";
- reg = <0x0 0xd0000000 0x0 0x200000>;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>;
+ pwm_d_pins: pwm_d {
+ mux {
+ groups = "pwm_d";
+ function = "pwm_d";
+ };
};
- usb0: usb@c9000000 {
- compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
- reg = <0x0 0xc9000000 0x0 0x40000>;
- interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clkc CLKID_USB0_DDR_BRIDGE>;
- clock-names = "otg";
- phys = <&usb0_phy>;
- phy-names = "usb2-phy";
- dr_mode = "host";
- status = "disabled";
+ pwm_e_pins: pwm_e {
+ mux {
+ groups = "pwm_e";
+ function = "pwm_e";
+ };
};
- usb1: usb@c9100000 {
- compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
- reg = <0x0 0xc9100000 0x0 0x40000>;
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clkc CLKID_USB1_DDR_BRIDGE>;
- clock-names = "otg";
- phys = <&usb1_phy>;
- phy-names = "usb2-phy";
- dr_mode = "host";
- status = "disabled";
+ pwm_f_x_pins: pwm_f_x {
+ mux {
+ groups = "pwm_f_x";
+ function = "pwm_f_x";
+ };
};
- ethmac: ethernet@c9410000 {
- compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
- reg = <0x0 0xc9410000 0x0 0x10000
- 0x0 0xc8834540 0x0 0x4>;
- interrupts = <0 8 1>;
- interrupt-names = "macirq";
- clocks = <&clkc CLKID_ETH>,
- <&clkc CLKID_FCLK_DIV2>,
- <&clkc CLKID_MPLL2>;
- clock-names = "stmmaceth", "clkin0", "clkin1";
- phy-mode = "rgmii";
- status = "disabled";
+ pwm_f_y_pins: pwm_f_y {
+ mux {
+ groups = "pwm_f_y";
+ function = "pwm_f_y";
+ };
};
};
};
+
+&hiubus {
+ clkc: clock-controller@0 {
+ compatible = "amlogic,gxbb-clkc";
+ #clock-cells = <1>;
+ reg = <0x0 0x0 0x0 0x3db>;
+ };
+};
+
+&i2c_A {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_B {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_C {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&sd_emmc_a {
+ clocks = <&clkc CLKID_SD_EMMC_A>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_b {
+ clocks = <&clkc CLKID_SD_EMMC_B>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_c {
+ clocks = <&clkc CLKID_SD_EMMC_C>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
new file mode 100644
index 000000000000..e99101ae9664
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Andreas Färber
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Author: Neil Armstrong <narmstrong@kernel.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
+ * 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 "meson-gxl-s905x.dtsi"
+
+/ {
+ compatible = "nexbox,a95x", "amlogic,s905x", "amlogic,meson-gxl";
+ model = "NEXBOX A95X (S905X)";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ vddio_card: gpio-regulator {
+ compatible = "regulator-gpio";
+
+ regulator-name = "VDDIO_CARD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+
+ /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
+ states = <1800000 0
+ 3300000 1>;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&ethmac {
+ status = "okay";
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_card>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&clkc CLKID_FCLK_DIV4>;
+ clock-names = "clkin0";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
new file mode 100644
index 000000000000..f66939cacd37
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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 "meson-gxl-s905d.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+ compatible = "amlogic,p230", "amlogic,s905d", "amlogic,meson-gxl";
+ model = "Amlogic Meson GXL (S905D) P230 Development Board";
+};
+
+/* P230 has exclusive choice between internal or external PHY */
+&ethmac {
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-names = "default";
+
+ /* Select external PHY by default */
+ phy-handle = <&external_phy>;
+
+ /* External PHY reset is shared with internal PHY Led signals */
+ snps,reset-gpio = <&gpio GPIOZ_14 0>;
+ snps,reset-delays-us = <0 10000 1000000>;
+ snps,reset-active-low;
+
+ /* External PHY is in RGMII */
+ phy-mode = "rgmii";
+};
+
+&external_mdio {
+ external_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ max-speed = <1000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
new file mode 100644
index 000000000000..95992cf1fe61
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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 "meson-gxl-s905d.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+ compatible = "amlogic,p231", "amlogic,s905d", "amlogic,meson-gxl";
+ model = "Amlogic Meson GXL (S905D) P231 Development Board";
+};
+
+/* P231 has only internal PHY port */
+&ethmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi
new file mode 100644
index 000000000000..615308e55576
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d.dtsi
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+#include "meson-gxl.dtsi"
+
+/ {
+ compatible = "amlogic,s905d", "amlogic,meson-gxl";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
new file mode 100644
index 000000000000..9639f012b02b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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 "meson-gxl-s905x.dtsi"
+
+/ {
+ compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
+ model = "Amlogic Meson GXL (S905X) P212 Development Board";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+};
+
+/* This UART is brought out to the DB9 connector */
+&uart_AO {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
new file mode 100644
index 000000000000..08237ee1e362
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+#include "meson-gxl.dtsi"
+
+/ {
+ compatible = "amlogic,s905x", "amlogic,meson-gxl";
+};
+
+/* S905X Only has access to its internal PHY */
+&ethmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
new file mode 100644
index 000000000000..9f89b99c4806
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+#include "meson-gx.dtsi"
+#include <dt-bindings/clock/gxbb-clkc.h>
+#include <dt-bindings/gpio/meson-gxbb-gpio.h>
+
+/ {
+ compatible = "amlogic,meson-gxl";
+};
+
+&ethmac {
+ reg = <0x0 0xc9410000 0x0 0x10000
+ 0x0 0xc8834540 0x0 0x4>;
+
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+
+ mdio0: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ };
+};
+
+&aobus {
+ pinctrl_aobus: pinctrl@14 {
+ compatible = "amlogic,meson-gxl-aobus-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio_ao: bank@14 {
+ reg = <0x0 0x00014 0x0 0x8>,
+ <0x0 0x0002c 0x0 0x4>,
+ <0x0 0x00024 0x0 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_tx_ao_a", "uart_rx_ao_a";
+ function = "uart_ao";
+ };
+ };
+
+ remote_input_ao_pins: remote_input_ao {
+ mux {
+ groups = "remote_input_ao";
+ function = "remote_input_ao";
+ };
+ };
+ };
+};
+
+&periphs {
+ pinctrl_periphs: pinctrl@4b0 {
+ compatible = "amlogic,meson-gxl-periphs-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio: bank@4b0 {
+ reg = <0x0 0x004b0 0x0 0x28>,
+ <0x0 0x004e8 0x0 0x14>,
+ <0x0 0x00120 0x0 0x14>,
+ <0x0 0x00430 0x0 0x40>;
+ reg-names = "mux", "pull", "pull-enable", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ emmc_pins: emmc {
+ mux {
+ groups = "emmc_nand_d07",
+ "emmc_cmd",
+ "emmc_clk",
+ "emmc_ds";
+ function = "emmc";
+ };
+ };
+
+ sdcard_pins: sdcard {
+ mux {
+ groups = "sdcard_d0",
+ "sdcard_d1",
+ "sdcard_d2",
+ "sdcard_d3",
+ "sdcard_cmd",
+ "sdcard_clk";
+ function = "sdcard";
+ };
+ };
+
+ sdio_pins: sdio {
+ mux {
+ groups = "sdio_d0",
+ "sdio_d1",
+ "sdio_d2",
+ "sdio_d3",
+ "sdio_cmd",
+ "sdio_clk";
+ function = "sdio";
+ };
+ };
+
+ sdio_irq_pins: sdio_irq {
+ mux {
+ groups = "sdio_irq";
+ function = "sdio";
+ };
+ };
+
+ uart_a_pins: uart_a {
+ mux {
+ groups = "uart_tx_a",
+ "uart_rx_a";
+ function = "uart_a";
+ };
+ };
+
+ uart_b_pins: uart_b {
+ mux {
+ groups = "uart_tx_b",
+ "uart_rx_b";
+ function = "uart_b";
+ };
+ };
+
+ uart_c_pins: uart_c {
+ mux {
+ groups = "uart_tx_c",
+ "uart_rx_c";
+ function = "uart_c";
+ };
+ };
+
+ i2c_a_pins: i2c_a {
+ mux {
+ groups = "i2c_sck_a",
+ "i2c_sda_a";
+ function = "i2c_a";
+ };
+ };
+
+ i2c_b_pins: i2c_b {
+ mux {
+ groups = "i2c_sck_b",
+ "i2c_sda_b";
+ function = "i2c_b";
+ };
+ };
+
+ i2c_c_pins: i2c_c {
+ mux {
+ groups = "i2c_sck_c",
+ "i2c_sda_c";
+ function = "i2c_c";
+ };
+ };
+
+ eth_pins: eth_c {
+ mux {
+ groups = "eth_mdio",
+ "eth_mdc",
+ "eth_clk_rx_clk",
+ "eth_rx_dv",
+ "eth_rxd0",
+ "eth_rxd1",
+ "eth_rxd2",
+ "eth_rxd3",
+ "eth_rgmii_tx_clk",
+ "eth_tx_en",
+ "eth_txd0",
+ "eth_txd1",
+ "eth_txd2",
+ "eth_txd3";
+ function = "eth";
+ };
+ };
+
+ pwm_e_pins: pwm_e {
+ mux {
+ groups = "pwm_e";
+ function = "pwm_e";
+ };
+ };
+ };
+
+ eth-phy-mux {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x55c 0x0 0x4>;
+ mux-mask = <0xffffffff>;
+ mdio-parent-bus = <&mdio0>;
+
+ internal_mdio: mdio@e40908ff {
+ reg = <0xe40908ff>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ internal_phy: ethernet-phy@8 {
+ compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+ reg = <8>;
+ max-speed = <100>;
+ };
+ };
+
+ external_mdio: mdio@2009087f {
+ reg = <0x2009087f>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&hiubus {
+ clkc: clock-controller@0 {
+ compatible = "amlogic,gxl-clkc", "amlogic,gxbb-clkc";
+ #clock-cells = <1>;
+ reg = <0x0 0x0 0x0 0x3db>;
+ };
+};
+
+&i2c_A {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_B {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&i2c_C {
+ clocks = <&clkc CLKID_I2C>;
+};
+
+&sd_emmc_a {
+ clocks = <&clkc CLKID_SD_EMMC_A>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_b {
+ clocks = <&clkc CLKID_SD_EMMC_B>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
+
+&sd_emmc_c {
+ clocks = <&clkc CLKID_SD_EMMC_C>,
+ <&xtal>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
new file mode 100644
index 000000000000..f859d75db8bd
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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 "meson-gxm.dtsi"
+
+/ {
+ compatible = "nexbox,a1", "amlogic,s912", "amlogic,meson-gxm";
+ model = "NEXBOX A1";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ vddio_boot: regulator-vddio-boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vddao_3v3: regulator-vddao-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_3v3: regulator-vcc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+};
+
+/* This UART is brought out to the DB9 connector */
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&ethmac {
+ status = "okay";
+
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-names = "default";
+
+ /* Select external PHY by default */
+ phy-handle = <&external_phy>;
+
+ snps,reset-gpio = <&gpio GPIOZ_14 0>;
+ snps,reset-delays-us = <0 10000 1000000>;
+ snps,reset-active-low;
+
+ /* External PHY is in RGMII */
+ phy-mode = "rgmii";
+};
+
+&external_mdio {
+ external_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ max-speed = <1000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts
new file mode 100644
index 000000000000..5dbc66088355
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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 "meson-gxm.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+ compatible = "amlogic,q200", "amlogic,s912", "amlogic,meson-gxm";
+ model = "Amlogic Meson GXM (S912) Q200 Development Board";
+};
+
+/* Q200 has exclusive choice between internal or external PHY */
+&ethmac {
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-names = "default";
+
+ /* Select external PHY by default */
+ phy-handle = <&external_phy>;
+
+ /* External PHY reset is shared with internal PHY Led signals */
+ snps,reset-gpio = <&gpio GPIOZ_14 0>;
+ snps,reset-delays-us = <0 10000 1000000>;
+ snps,reset-active-low;
+
+ /* External PHY is in RGMII */
+ phy-mode = "rgmii";
+};
+
+&external_mdio {
+ external_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ max-speed = <1000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q201.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q201.dts
new file mode 100644
index 000000000000..95e11d7faab8
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q201.dts
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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 "meson-gxm.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+ compatible = "amlogic,q201", "amlogic,s912", "amlogic,meson-gxm";
+ model = "Amlogic Meson GXM (S912) Q201 Development Board";
+};
+
+/* Q201 has only internal PHY port */
+&ethmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
new file mode 100644
index 000000000000..c1974bbbddea
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016 Endless Computers, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+#include "meson-gxl.dtsi"
+
+/ {
+ compatible = "amlogic,meson-gxm";
+
+ cpus {
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ core2 {
+ cpu = <&cpu2>;
+ };
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu4>;
+ };
+ core1 {
+ cpu = <&cpu5>;
+ };
+ core2 {
+ cpu = <&cpu6>;
+ };
+ core3 {
+ cpu = <&cpu7>;
+ };
+ };
+ };
+
+ cpu4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x101>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x102>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x103>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 7d3a2acc6a55..7d832247d0db 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -29,6 +29,28 @@
clock-names = "apb_pclk";
};
+ smmu_pcie: iommu@2b500000 {
+ compatible = "arm,mmu-401", "arm,smmu-v1";
+ reg = <0x0 0x2b500000 0x0 0x10000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ #global-interrupts = <1>;
+ dma-coherent;
+ status = "disabled";
+ };
+
+ smmu_etr: iommu@2b600000 {
+ compatible = "arm,mmu-401", "arm,smmu-v1";
+ reg = <0x0 0x2b600000 0x0 0x10000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ #global-interrupts = <1>;
+ dma-coherent;
+ status = "disabled";
+ };
+
gic: interrupt-controller@2c010000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
reg = <0x0 0x2c010000 0 0x1000>,
@@ -146,6 +168,7 @@
etr@20070000 {
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0 0x20070000 0 0x1000>;
+ iommus = <&smmu_etr 0>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
@@ -404,6 +427,8 @@
<0 0 0 4 &gic 0 0 0 139 4>;
msi-parent = <&v2m_0>;
status = "disabled";
+ iommu-map-mask = <0x0>; /* RC has no means to output PCI RID */
+ iommu-map = <0x0 &smmu_pcie 0x0 0x1>;
};
scpi {
@@ -484,6 +509,48 @@
/include/ "juno-clocks.dtsi"
+ smmu_dma: iommu@7fb00000 {
+ compatible = "arm,mmu-401", "arm,smmu-v1";
+ reg = <0x0 0x7fb00000 0x0 0x10000>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ #global-interrupts = <1>;
+ dma-coherent;
+ status = "disabled";
+ };
+
+ smmu_hdlcd1: iommu@7fb10000 {
+ compatible = "arm,mmu-401", "arm,smmu-v1";
+ reg = <0x0 0x7fb10000 0x0 0x10000>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ #global-interrupts = <1>;
+ status = "disabled";
+ };
+
+ smmu_hdlcd0: iommu@7fb20000 {
+ compatible = "arm,mmu-401", "arm,smmu-v1";
+ reg = <0x0 0x7fb20000 0x0 0x10000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ #global-interrupts = <1>;
+ status = "disabled";
+ };
+
+ smmu_usb: iommu@7fb30000 {
+ compatible = "arm,mmu-401", "arm,smmu-v1";
+ reg = <0x0 0x7fb30000 0x0 0x10000>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ #global-interrupts = <1>;
+ dma-coherent;
+ status = "disabled";
+ };
+
dma@7ff00000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0x7ff00000 0 0x1000>;
@@ -499,6 +566,15 @@
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu_dma 0>,
+ <&smmu_dma 1>,
+ <&smmu_dma 2>,
+ <&smmu_dma 3>,
+ <&smmu_dma 4>,
+ <&smmu_dma 5>,
+ <&smmu_dma 6>,
+ <&smmu_dma 7>,
+ <&smmu_dma 8>;
clocks = <&soc_faxiclk>;
clock-names = "apb_pclk";
};
@@ -507,6 +583,7 @@
compatible = "arm,hdlcd";
reg = <0 0x7ff50000 0 0x1000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu_hdlcd1 0>;
clocks = <&scpi_clk 3>;
clock-names = "pxlclk";
@@ -521,6 +598,7 @@
compatible = "arm,hdlcd";
reg = <0 0x7ff60000 0 0x1000>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu_hdlcd0 0>;
clocks = <&scpi_clk 3>;
clock-names = "pxlclk";
@@ -574,6 +652,7 @@
compatible = "generic-ohci";
reg = <0x0 0x7ffb0000 0x0 0x10000>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu_usb 0>;
clocks = <&soc_usb48mhz>;
};
@@ -581,6 +660,7 @@
compatible = "generic-ehci";
reg = <0x0 0x7ffc0000 0x0 0x10000>;
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu_usb 0>;
clocks = <&soc_usb48mhz>;
};
diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts
index f0b857d6d73c..eec37feee8fc 100644
--- a/arch/arm64/boot/dts/arm/juno-r1.dts
+++ b/arch/arm64/boot/dts/arm/juno-r1.dts
@@ -90,6 +90,7 @@
next-level-cache = <&A57_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <1024>;
};
A57_1: cpu@1 {
@@ -100,6 +101,7 @@
next-level-cache = <&A57_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <1024>;
};
A53_0: cpu@100 {
@@ -110,6 +112,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A53_1: cpu@101 {
@@ -120,6 +123,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A53_2: cpu@102 {
@@ -130,6 +134,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A53_3: cpu@103 {
@@ -140,6 +145,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A57_L2: l2-cache0 {
diff --git a/arch/arm64/boot/dts/arm/juno-r2.dts b/arch/arm64/boot/dts/arm/juno-r2.dts
index 26aaa6a7670f..28f40ec44090 100644
--- a/arch/arm64/boot/dts/arm/juno-r2.dts
+++ b/arch/arm64/boot/dts/arm/juno-r2.dts
@@ -90,6 +90,7 @@
next-level-cache = <&A72_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <1024>;
};
A72_1: cpu@1 {
@@ -100,6 +101,7 @@
next-level-cache = <&A72_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <1024>;
};
A53_0: cpu@100 {
@@ -110,6 +112,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <485>;
};
A53_1: cpu@101 {
@@ -120,6 +123,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <485>;
};
A53_2: cpu@102 {
@@ -130,6 +134,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <485>;
};
A53_3: cpu@103 {
@@ -140,6 +145,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <485>;
};
A72_L2: l2-cache0 {
diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
index 6e154d948a80..ac5ceb73f45f 100644
--- a/arch/arm64/boot/dts/arm/juno.dts
+++ b/arch/arm64/boot/dts/arm/juno.dts
@@ -90,6 +90,7 @@
next-level-cache = <&A57_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <1024>;
};
A57_1: cpu@1 {
@@ -100,6 +101,7 @@
next-level-cache = <&A57_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <1024>;
};
A53_0: cpu@100 {
@@ -110,6 +112,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A53_1: cpu@101 {
@@ -120,6 +123,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A53_2: cpu@102 {
@@ -130,6 +134,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A53_3: cpu@103 {
@@ -140,6 +145,7 @@
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ capacity-dmips-mhz = <578>;
};
A57_L2: l2-cache0 {
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 7841b724e340..c309633a1e87 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -2,6 +2,7 @@
#include "bcm2837.dtsi"
#include "bcm2835-rpi.dtsi"
#include "bcm283x-rpi-smsc9514.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
/ {
compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
@@ -15,13 +16,6 @@
act {
gpios = <&gpio 47 0>;
};
-
- pwr {
- label = "PWR";
- gpios = <&gpio 35 0>;
- default-state = "keep";
- linux,default-trigger = "default-on";
- };
};
};
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
index 8216bbb29fe0..19f2fe620a21 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
@@ -1,7 +1,7 @@
#include "bcm283x.dtsi"
/ {
- compatible = "brcm,bcm2836";
+ compatible = "brcm,bcm2837";
soc {
ranges = <0x7e000000 0x3f000000 0x1000000>,
@@ -74,3 +74,9 @@
interrupt-parent = <&local_intc>;
interrupts = <8>;
};
+
+/* enable thermal sensor with the correct compatible property set */
+&thermal {
+ compatible = "brcm,bcm2837-thermal";
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi
new file mode 120000
index 000000000000..cbeebe312ff8
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi
@@ -0,0 +1 @@
+../../../../arm/boot/dts/bcm283x-rpi-usb-host.dtsi \ No newline at end of file
diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index c4d544244b19..de8d379f44e2 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -161,6 +161,10 @@
status = "ok";
};
+&sdio1 {
+ status = "ok";
+};
+
&nand {
nandcs@0 {
compatible = "brcm,nandcs";
@@ -192,3 +196,37 @@
groups = "nand_grp";
};
};
+
+&qspi {
+ bspi-sel = <0>;
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p80";
+ reg = <0x0>;
+ spi-max-frequency = <12500000>;
+ m25p,fast-read;
+ spi-cpol;
+ spi-cpha;
+
+ partition@0 {
+ label = "boot";
+ reg = <0x00000000 0x000a0000>;
+ };
+
+ partition@a0000 {
+ label = "env";
+ reg = <0x000a0000 0x00060000>;
+ };
+
+ partition@100000 {
+ label = "system";
+ reg = <0x00100000 0x00600000>;
+ };
+
+ partition@700000 {
+ label = "rootfs";
+ reg = <0x00700000 0x01900000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index 773ed593da4d..4fcdeca3a983 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -133,6 +133,9 @@
status = "disabled";
+ phys = <&pci_phy0>;
+ phy-names = "pcie-phy";
+
msi-parent = <&msi0>;
msi0: msi@20020000 {
compatible = "brcm,iproc-msi";
@@ -171,6 +174,9 @@
status = "disabled";
+ phys = <&pci_phy1>;
+ phy-names = "pcie-phy";
+
msi-parent = <&msi4>;
msi4: msi@50020000 {
compatible = "brcm,iproc-msi";
@@ -203,6 +209,42 @@
status = "disabled";
};
+ pdc0: iproc-pdc0@612c0000 {
+ compatible = "brcm,iproc-pdc-mbox";
+ reg = <0x612c0000 0x445>; /* PDC FS0 regs */
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ brcm,rx-status-len = <32>;
+ brcm,use-bcm-hdr;
+ };
+
+ pdc1: iproc-pdc1@612e0000 {
+ compatible = "brcm,iproc-pdc-mbox";
+ reg = <0x612e0000 0x445>; /* PDC FS1 regs */
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ brcm,rx-status-len = <32>;
+ brcm,use-bcm-hdr;
+ };
+
+ pdc2: iproc-pdc2@61300000 {
+ compatible = "brcm,iproc-pdc-mbox";
+ reg = <0x61300000 0x445>; /* PDC FS2 regs */
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ brcm,rx-status-len = <32>;
+ brcm,use-bcm-hdr;
+ };
+
+ pdc3: iproc-pdc3@61320000 {
+ compatible = "brcm,iproc-pdc-mbox";
+ reg = <0x61320000 0x445>; /* PDC FS3 regs */
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ brcm,rx-status-len = <32>;
+ brcm,use-bcm-hdr;
+ };
+
dma0: dma@61360000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x61360000 0x1000>;
@@ -260,7 +302,7 @@
<GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
- mmu-masters;
+ #iommu-cells = <1>;
};
pinctrl: pinctrl@6501d130 {
@@ -577,5 +619,23 @@
brcm,nand-has-wp;
};
+
+ qspi: spi@66470200 {
+ compatible = "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi";
+ reg = <0x66470200 0x184>,
+ <0x66470000 0x124>,
+ <0x67017408 0x004>,
+ <0x664703a0 0x01c>;
+ reg-names = "mspi", "bspi", "intr_regs",
+ "intr_status_reg";
+ interrupts = <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "spi_l1_intr";
+ clocks = <&iprocmed>;
+ clock-names = "iprocmed";
+ num-cs = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
};
};
diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 50c9b9383cfa..7ddea53769a7 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -1,4 +1,7 @@
-dtb-$(CONFIG_ARCH_EXYNOS) += exynos7-espresso.dtb
+dtb-$(CONFIG_ARCH_EXYNOS) += \
+ exynos5433-tm2.dtb \
+ exynos5433-tm2e.dtb \
+ exynos7-espresso.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
new file mode 100644
index 000000000000..ad71247b074f
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
@@ -0,0 +1,804 @@
+/*
+ * Samsung's Exynos5433 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Chanwoo Choi <cw00.choi@samsung.com>
+ *
+ * Samsung's Exynos5433 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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 PIN_PULL_NONE 0
+#define PIN_PULL_DOWN 1
+#define PIN_PULL_UP 3
+
+#define PIN_DRV_LV1 0
+#define PIN_DRV_LV2 2
+#define PIN_DRV_LV3 1
+#define PIN_DRV_LV4 3
+
+#define PIN_IN 0
+#define PIN_OUT 1
+#define PIN_FUNC1 2
+
+#define PIN(_func, _pin, _pull, _drv) \
+ _pin { \
+ samsung,pins = #_pin; \
+ samsung,pin-function = <PIN_ ##_func>; \
+ samsung,pin-pud = <PIN_PULL_ ##_pull>; \
+ samsung,pin-drv = <PIN_DRV_ ##_drv>; \
+ }
+
+&pinctrl_alive {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa3: gpa3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf3: gpf3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf4: gpf4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf5: gpf5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&pinctrl_aud {
+ gpz0: gpz0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpz1: gpz1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2s0_bus: i2s0-bus {
+ samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
+ "gpz0-4", "gpz0-5", "gpz0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm0_bus: pcm0-bus {
+ samsung,pins = "gpz1-0", "gpz1-1", "gpz1-2", "gpz1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart_aud_bus: uart-aud-bus {
+ samsung,pins = "gpz1-3", "gpz1-2", "gpz1-1", "gpz1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_cpif {
+ gpv6: gpv6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&pinctrl_ese {
+ gpj2: gpj2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&pinctrl_finger {
+ gpd5: gpd5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpd5-0", "gpd5-2", "gpd5-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c6_bus: hs-i2c6-bus {
+ samsung,pins = "gpd5-3", "gpd5-2";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_fsys {
+ gph1: gph1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr4: gpr4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr0: gpr0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr1: gpr1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr2: gpr2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr3: gpr3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpr0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_rdqs: sd0-rdqs {
+ samsung,pins = "gpr0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_qrdy: sd0-qrdy {
+ samsung,pins = "gpr0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpr1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpr2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpr2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpr3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus8: sd1-bus-width8 {
+ samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ pcie_bus: pcie_bus {
+ samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpr4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpr4-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpr4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk_output: sd2-clk-output {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_cmd_output: sd2-cmd-output {
+ samsung,pins = "gpr4-1";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+};
+
+&pinctrl_imem {
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&pinctrl_nfc {
+ gpj0: gpj0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c4_bus: hs-i2c4-bus {
+ samsung,pins = "gpj0-1", "gpj0-0";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_peric {
+ gpv7: gpv7 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc3: gpc3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd2: gpd2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd4: gpd4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd8: gpd8 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd6: gpd6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd7: gpd7 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg3: gpg3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c8_bus: hs-i2c8-bus {
+ samsung,pins = "gpb0-1", "gpb0-0";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c9_bus: hs-i2c9-bus {
+ samsung,pins = "gpb0-3", "gpb0-2";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s1_bus: i2s1-bus {
+ samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
+ "gpd4-3", "gpd4-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ pcm1_bus: pcm1-bus {
+ samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
+ "gpd4-3", "gpd4-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ spdif_bus: spdif-bus {
+ samsung,pins = "gpd4-3", "gpd4-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_spi_pin0: fimc-is-spi-pin0 {
+ samsung,pins = "gpc3-3", "gpc3-2", "gpc3-1", "gpc3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_spi_pin1: fimc-is-spi-pin1 {
+ samsung,pins = "gpc3-7", "gpc3-6", "gpc3-5", "gpc3-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_bus: uart0-bus {
+ samsung,pins = "gpd0-3", "gpd0-2", "gpd0-1", "gpd0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ };
+
+ hs_i2c2_bus: hs-i2c2-bus {
+ samsung,pins = "gpd0-3", "gpd0-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_bus: uart2-bus {
+ samsung,pins = "gpd1-5", "gpd1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ };
+
+ uart1_bus: uart1-bus {
+ samsung,pins = "gpd1-3", "gpd1-2", "gpd1-1", "gpd1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ };
+
+ hs_i2c3_bus: hs-i2c3-bus {
+ samsung,pins = "gpd1-3", "gpd1-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c0_bus: hs-i2c0-bus {
+ samsung,pins = "gpd2-1", "gpd2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c1_bus: hs-i2c1-bus {
+ samsung,pins = "gpd2-3", "gpd2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd2-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd2-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd2-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpd6-2", "gpd6-4", "gpd6-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c7_bus: hs-i2c7-bus {
+ samsung,pins = "gpd2-7", "gpd2-6";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpd8-0", "gpd6-0", "gpd6-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c10_bus: hs-i2c10-bus {
+ samsung,pins = "gpg3-1", "gpg3-0";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c11_bus: hs-i2c11-bus {
+ samsung,pins = "gpg3-3", "gpg3-2";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi3_bus: spi3-bus {
+ samsung,pins = "gpg3-4", "gpg3-6", "gpg3-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi4_bus: spi4-bus {
+ samsung,pins = "gpv7-1", "gpv7-3", "gpv7-4";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_uart: fimc-is-uart {
+ samsung,pins = "gpc1-1", "gpc0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_ch0_i2c: fimc-is-ch0_i2c {
+ samsung,pins = "gpc2-1", "gpc2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_ch0_mclk: fimc-is-ch0_mclk {
+ samsung,pins = "gpd7-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_ch1_i2c: fimc-is-ch1-i2c {
+ samsung,pins = "gpc2-3", "gpc2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_ch1_mclk: fimc-is-ch1-mclk {
+ samsung,pins = "gpd7-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_ch2_i2c: fimc-is-ch2-i2c {
+ samsung,pins = "gpc2-5", "gpc2-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ fimc_is_ch2_mclk: fimc-is-ch2-mclk {
+ samsung,pins = "gpd7-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_touch {
+ gpj1: gpj1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c5_bus: hs-i2c5-bus {
+ samsung,pins = "gpj1-1", "gpj1-0";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
new file mode 100644
index 000000000000..f21bdc2ff834
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -0,0 +1,1049 @@
+/*
+ * SAMSUNG Exynos5433 TM2 board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Device tree source file for Samsung's TM2 board which is based on
+ * Samsung Exynos5433 SoC.
+ *
+ * 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 "exynos5433.dtsi"
+#include <dt-bindings/clock/samsung,s2mps11.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "Samsung TM2 board";
+ compatible = "samsung,tm2", "samsung,exynos5433";
+
+ aliases {
+ gsc0 = &gsc_0;
+ gsc1 = &gsc_1;
+ gsc2 = &gsc_2;
+ pinctrl0 = &pinctrl_alive;
+ pinctrl1 = &pinctrl_aud;
+ pinctrl2 = &pinctrl_cpif;
+ pinctrl3 = &pinctrl_ese;
+ pinctrl4 = &pinctrl_finger;
+ pinctrl5 = &pinctrl_fsys;
+ pinctrl6 = &pinctrl_imem;
+ pinctrl7 = &pinctrl_nfc;
+ pinctrl8 = &pinctrl_peric;
+ pinctrl9 = &pinctrl_touch;
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ serial2 = &serial_2;
+ serial3 = &serial_3;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ spi3 = &spi_3;
+ spi4 = &spi_4;
+ mshc0 = &mshc_0;
+ mshc2 = &mshc_2;
+ };
+
+ chosen {
+ stdout-path = &serial_1;
+ };
+
+ memory@20000000 {
+ device_type = "memory";
+ reg = <0x0 0x20000000 0x0 0xc0000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power-key {
+ gpios = <&gpa2 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "power key";
+ debounce-interval = <10>;
+ };
+
+ volume-up-key {
+ gpios = <&gpa2 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ label = "volume-up key";
+ debounce-interval = <10>;
+ };
+
+ volume-down-key {
+ gpios = <&gpa2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ label = "volume-down key";
+ debounce-interval = <10>;
+ };
+
+ homepage-key {
+ gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ label = "homepage key";
+ debounce-interval = <10>;
+ };
+ };
+
+ i2c_max98504: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ gpios = <&gpd0 1 GPIO_ACTIVE_HIGH /* SPK_AMP_SDA */
+ &gpd0 0 GPIO_ACTIVE_HIGH /* SPK_AMP_SCL */ >;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ max98504: max98504@31 {
+ compatible = "maxim,max98504";
+ reg = <0x31>;
+ maxim,rx-path = <1>;
+ maxim,tx-path = <1>;
+ maxim,tx-channel-mask = <3>;
+ maxim,tx-channel-source = <2>;
+ };
+ };
+
+ sound {
+ compatible = "samsung,tm2-audio";
+ audio-codec = <&wm5110>;
+ i2s-controller = <&i2s0>;
+ audio-amplifier = <&max98504>;
+ mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
+ model = "wm5110";
+ samsung,audio-routing =
+ /* Headphone */
+ "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
+
+ /* Speaker */
+ "SPK", "SPKOUT",
+ "SPKOUT", "HPOUT2L",
+ "SPKOUT", "HPOUT2R",
+
+ /* Receiver */
+ "RCV", "HPOUT3L",
+ "RCV", "HPOUT3R";
+ status = "okay";
+ };
+};
+
+&adc {
+ vdd-supply = <&ldo3_reg>;
+ status = "okay";
+
+ thermistor-ap {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 0>;
+ };
+
+ thermistor-battery {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 1>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermistor-charger {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 2>;
+ };
+};
+
+&cmu_aud {
+ assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>;
+ assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>;
+};
+
+&cmu_fsys {
+ assigned-clocks = <&cmu_top CLK_MOUT_SCLK_USBDRD30>,
+ <&cmu_top CLK_MOUT_SCLK_USBHOST30>,
+ <&cmu_fsys CLK_MOUT_SCLK_USBDRD30_USER>,
+ <&cmu_fsys CLK_MOUT_SCLK_USBHOST30_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER>,
+ <&cmu_top CLK_DIV_SCLK_USBDRD30>,
+ <&cmu_top CLK_DIV_SCLK_USBHOST30>;
+ assigned-clock-parents = <&cmu_top CLK_MOUT_BUS_PLL_USER>,
+ <&cmu_top CLK_MOUT_BUS_PLL_USER>,
+ <&cmu_top CLK_SCLK_USBDRD30_FSYS>,
+ <&cmu_top CLK_SCLK_USBHOST30_FSYS>,
+ <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY>,
+ <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY>,
+ <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY>,
+ <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY>;
+ assigned-clock-rates = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>,
+ <66700000>, <66700000>;
+};
+
+&cmu_gscl {
+ assigned-clocks = <&cmu_gscl CLK_MOUT_ACLK_GSCL_111_USER>,
+ <&cmu_gscl CLK_MOUT_ACLK_GSCL_333_USER>;
+ assigned-clock-parents = <&cmu_top CLK_ACLK_GSCL_111>,
+ <&cmu_top CLK_ACLK_GSCL_333>;
+};
+
+&cmu_mfc {
+ assigned-clocks = <&cmu_mfc CLK_MOUT_ACLK_MFC_400_USER>;
+ assigned-clock-parents = <&cmu_top CLK_ACLK_MFC_400>;
+};
+
+&cmu_mscl {
+ assigned-clocks = <&cmu_mscl CLK_MOUT_ACLK_MSCL_400_USER>,
+ <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
+ <&cmu_mscl CLK_MOUT_SCLK_JPEG>,
+ <&cmu_top CLK_MOUT_SCLK_JPEG_A>;
+ assigned-clock-parents = <&cmu_top CLK_ACLK_MSCL_400>,
+ <&cmu_top CLK_SCLK_JPEG_MSCL>,
+ <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
+ <&cmu_top CLK_MOUT_BUS_PLL_USER>;
+};
+
+&cpu0 {
+ cpu-supply = <&buck3_reg>;
+};
+
+&cpu4 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&decon {
+ status = "okay";
+
+ i80-if-timings {
+ };
+};
+
+&dsi {
+ status = "okay";
+ vddcore-supply = <&ldo6_reg>;
+ vddio-supply = <&ldo7_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&te_irq>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dsi_out: endpoint {
+ samsung,burst-clock-frequency = <512000000>;
+ samsung,esc-clock-frequency = <16000000>;
+ };
+ };
+ };
+};
+
+&hsi2c_0 {
+ status = "okay";
+ clock-frequency = <2500000>;
+
+ s2mps13-pmic@66 {
+ compatible = "samsung,s2mps13-pmic";
+ interrupt-parent = <&gpa0>;
+ interrupts = <7 IRQ_TYPE_NONE>;
+ reg = <0x66>;
+ samsung,s2mps11-wrstbi-ground;
+
+ s2mps13_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_ALIVE_0.9V_AP";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDDQ_MMC2_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDD1_E_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDD10_MIF_PLL_1.0V_AP";
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VDD10_DPLL_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD10_MIPI2L_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD18_MIPI2L_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VDD18_LLI_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VDD18_ABB_ETC_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDD33_USB30_3.0V_AP";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD_INT_M_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD_KFC_M_1.1V_AP";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDD_G3D_M_0.95V_AP";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <950000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDDQ_M1_LDO_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDDQ_M2_LDO_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDDQ_EFUSE";
+ regulator-min-microvolt = <1400000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "V_TFLASH_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "V_CODEC_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "VDDA_1.8V_COMP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "VCC_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "VT_CAM_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "CAM_IO_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "CAM_SEN_CORE_1.2V_AP";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "VT_CAM_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "CAM_SEN_A2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "CAM_AF_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "VCC_3.0V_LCD_AP";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "VCC_1.8V_LCD_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo29_reg: LDO29 {
+ regulator-name = "VT_CAM_2.8V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo30_reg: LDO30 {
+ regulator-name = "TSP_AVDD_3.3V_AP";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo31_reg: LDO31 {
+ regulator-name = "TSP_VDD_1.85V_AP";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
+
+ ldo32_reg: LDO32 {
+ regulator-name = "VTOUCH_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo33_reg: LDO33 {
+ regulator-name = "VTOUCH_LED_3.3V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ };
+
+ ldo34_reg: LDO34 {
+ regulator-name = "VCC_1.8V_MHL_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <2100000>;
+ };
+
+ ldo35_reg: LDO35 {
+ regulator-name = "OIS_VM_2.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo36_reg: LDO36 {
+ regulator-name = "VSIL_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo37_reg: LDO37 {
+ regulator-name = "VF_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo38_reg: LDO38 {
+ regulator-name = "VCC_3.0V_MOTOR_AP";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo39_reg: LDO39 {
+ regulator-name = "V_HRM_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo40_reg: LDO40 {
+ regulator-name = "V_HRM_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VDD_MIF_0.9V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VDD_EGL_1.0V_AP";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VDD_KFC_1.0V_AP";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "VDD_INT_0.95V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VDD_DISP_CAM0_0.9V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "VDD_G3D_0.9V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "VDD_MEM1_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "VDD_LLDO_1.35V_AP";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "VDD_MLDO_2.0V_AP";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_mem2";
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&hsi2c_8 {
+ status = "okay";
+
+ max77843@66 {
+ compatible = "maxim,max77843";
+ interrupt-parent = <&gpa1>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ reg = <0x66>;
+
+ muic: max77843-muic {
+ compatible = "maxim,max77843-muic";
+ };
+
+ regulators {
+ compatible = "maxim,max77843-regulator";
+ safeout1_reg: SAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <4950000>;
+ };
+
+ safeout2_reg: SAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <4950000>;
+ };
+
+ charger_reg: CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <100000>;
+ regulator-max-microamp = <3150000>;
+ };
+ };
+
+ haptic: max77843-haptic {
+ compatible = "maxim,max77843-haptic";
+ haptic-supply = <&ldo38_reg>;
+ pwms = <&pwm 0 33670 0>;
+ pwm-names = "haptic";
+ };
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mshc_0 {
+ status = "okay";
+ num-slots = <1>;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ cap-mmc-highspeed;
+ non-removable;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-hs400-timing = <0 3>;
+ samsung,read-strobe-delay = <90>;
+ fifo-depth = <0x80>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4
+ &sd0_bus8 &sd0_rdqs>;
+ bus-width = <8>;
+ assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>;
+ assigned-clock-rates = <800000000>;
+};
+
+&mshc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ disable-wp;
+ cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ fifo-depth = <0x80>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+};
+
+&pinctrl_alive {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_alive>;
+
+ initial_alive: initial-state {
+ PIN(IN, gpa0-0, DOWN, LV1);
+ PIN(IN, gpa0-1, NONE, LV1);
+ PIN(IN, gpa0-2, DOWN, LV1);
+ PIN(IN, gpa0-3, NONE, LV1);
+ PIN(IN, gpa0-4, NONE, LV1);
+ PIN(IN, gpa0-5, DOWN, LV1);
+ PIN(IN, gpa0-6, NONE, LV1);
+ PIN(IN, gpa0-7, NONE, LV1);
+
+ PIN(IN, gpa1-0, UP, LV1);
+ PIN(IN, gpa1-1, NONE, LV1);
+ PIN(IN, gpa1-2, NONE, LV1);
+ PIN(IN, gpa1-3, DOWN, LV1);
+ PIN(IN, gpa1-4, DOWN, LV1);
+ PIN(IN, gpa1-5, NONE, LV1);
+ PIN(IN, gpa1-6, NONE, LV1);
+ PIN(IN, gpa1-7, NONE, LV1);
+
+ PIN(IN, gpa2-0, NONE, LV1);
+ PIN(IN, gpa2-1, NONE, LV1);
+ PIN(IN, gpa2-2, NONE, LV1);
+ PIN(IN, gpa2-3, DOWN, LV1);
+ PIN(IN, gpa2-4, NONE, LV1);
+ PIN(IN, gpa2-5, DOWN, LV1);
+ PIN(IN, gpa2-6, DOWN, LV1);
+ PIN(IN, gpa2-7, NONE, LV1);
+
+ PIN(IN, gpa3-0, DOWN, LV1);
+ PIN(IN, gpa3-1, DOWN, LV1);
+ PIN(IN, gpa3-2, NONE, LV1);
+ PIN(IN, gpa3-3, DOWN, LV1);
+ PIN(IN, gpa3-4, NONE, LV1);
+ PIN(IN, gpa3-5, DOWN, LV1);
+ PIN(IN, gpa3-6, DOWN, LV1);
+ PIN(IN, gpa3-7, DOWN, LV1);
+
+ PIN(IN, gpf1-0, NONE, LV1);
+ PIN(IN, gpf1-1, NONE, LV1);
+ PIN(IN, gpf1-2, DOWN, LV1);
+ PIN(IN, gpf1-4, UP, LV1);
+ PIN(OUT, gpf1-5, NONE, LV1);
+ PIN(IN, gpf1-6, DOWN, LV1);
+ PIN(IN, gpf1-7, DOWN, LV1);
+
+ PIN(IN, gpf2-0, DOWN, LV1);
+ PIN(IN, gpf2-1, DOWN, LV1);
+ PIN(IN, gpf2-2, DOWN, LV1);
+ PIN(IN, gpf2-3, DOWN, LV1);
+
+ PIN(IN, gpf3-0, DOWN, LV1);
+ PIN(IN, gpf3-1, DOWN, LV1);
+ PIN(IN, gpf3-2, NONE, LV1);
+ PIN(IN, gpf3-3, DOWN, LV1);
+
+ PIN(IN, gpf4-0, DOWN, LV1);
+ PIN(IN, gpf4-1, DOWN, LV1);
+ PIN(IN, gpf4-2, DOWN, LV1);
+ PIN(IN, gpf4-3, DOWN, LV1);
+ PIN(IN, gpf4-4, DOWN, LV1);
+ PIN(IN, gpf4-5, DOWN, LV1);
+ PIN(IN, gpf4-6, DOWN, LV1);
+ PIN(IN, gpf4-7, DOWN, LV1);
+
+ PIN(IN, gpf5-0, DOWN, LV1);
+ PIN(IN, gpf5-1, DOWN, LV1);
+ PIN(IN, gpf5-2, DOWN, LV1);
+ PIN(IN, gpf5-3, DOWN, LV1);
+ PIN(OUT, gpf5-4, NONE, LV1);
+ PIN(IN, gpf5-5, DOWN, LV1);
+ PIN(IN, gpf5-6, DOWN, LV1);
+ PIN(IN, gpf5-7, DOWN, LV1);
+ };
+
+ te_irq: te_irq {
+ samsung,pins = "gpf1-3";
+ samsung,pin-function = <0xf>;
+ };
+};
+
+&pinctrl_cpif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_cpif>;
+
+ initial_cpif: initial-state {
+ PIN(IN, gpv6-0, DOWN, LV1);
+ PIN(IN, gpv6-1, DOWN, LV1);
+ };
+};
+
+&pinctrl_ese {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_ese>;
+
+ initial_ese: initial-state {
+ PIN(IN, gpj2-0, DOWN, LV1);
+ PIN(IN, gpj2-1, DOWN, LV1);
+ PIN(IN, gpj2-2, DOWN, LV1);
+ };
+};
+
+&pinctrl_fsys {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_fsys>;
+
+ initial_fsys: initial-state {
+ PIN(IN, gpr3-0, NONE, LV1);
+ PIN(IN, gpr3-1, DOWN, LV1);
+ PIN(IN, gpr3-2, DOWN, LV1);
+ PIN(IN, gpr3-3, DOWN, LV1);
+ PIN(IN, gpr3-7, NONE, LV1);
+ };
+};
+
+&pinctrl_imem {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_imem>;
+
+ initial_imem: initial-state {
+ PIN(IN, gpf0-0, UP, LV1);
+ PIN(IN, gpf0-1, UP, LV1);
+ PIN(IN, gpf0-2, DOWN, LV1);
+ PIN(IN, gpf0-3, UP, LV1);
+ PIN(IN, gpf0-4, DOWN, LV1);
+ PIN(IN, gpf0-5, NONE, LV1);
+ PIN(IN, gpf0-6, DOWN, LV1);
+ PIN(IN, gpf0-7, UP, LV1);
+ };
+};
+
+&pinctrl_nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_nfc>;
+
+ initial_nfc: initial-state {
+ PIN(IN, gpj0-2, DOWN, LV1);
+ };
+};
+
+&pinctrl_peric {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_peric>;
+
+ initial_peric: initial-state {
+ PIN(IN, gpv7-0, DOWN, LV1);
+ PIN(IN, gpv7-1, DOWN, LV1);
+ PIN(IN, gpv7-2, NONE, LV1);
+ PIN(IN, gpv7-3, DOWN, LV1);
+ PIN(IN, gpv7-4, DOWN, LV1);
+ PIN(IN, gpv7-5, DOWN, LV1);
+
+ PIN(IN, gpb0-4, DOWN, LV1);
+
+ PIN(IN, gpc0-2, DOWN, LV1);
+ PIN(IN, gpc0-5, DOWN, LV1);
+ PIN(IN, gpc0-7, DOWN, LV1);
+
+ PIN(IN, gpc1-1, DOWN, LV1);
+
+ PIN(IN, gpc3-4, NONE, LV1);
+ PIN(IN, gpc3-5, NONE, LV1);
+ PIN(IN, gpc3-6, NONE, LV1);
+ PIN(IN, gpc3-7, NONE, LV1);
+
+ PIN(OUT, gpg0-0, NONE, LV1);
+ PIN(FUNC1, gpg0-1, DOWN, LV1);
+
+ PIN(IN, gpd2-5, DOWN, LV1);
+
+ PIN(IN, gpd4-0, NONE, LV1);
+ PIN(IN, gpd4-1, DOWN, LV1);
+ PIN(IN, gpd4-2, DOWN, LV1);
+ PIN(IN, gpd4-3, DOWN, LV1);
+ PIN(IN, gpd4-4, DOWN, LV1);
+
+ PIN(IN, gpd6-3, DOWN, LV1);
+
+ PIN(IN, gpd8-1, UP, LV1);
+
+ PIN(IN, gpg1-0, DOWN, LV1);
+ PIN(IN, gpg1-1, DOWN, LV1);
+ PIN(IN, gpg1-2, DOWN, LV1);
+ PIN(IN, gpg1-3, DOWN, LV1);
+ PIN(IN, gpg1-4, DOWN, LV1);
+
+ PIN(IN, gpg2-0, DOWN, LV1);
+ PIN(IN, gpg2-1, DOWN, LV1);
+
+ PIN(IN, gpg3-0, DOWN, LV1);
+ PIN(IN, gpg3-1, DOWN, LV1);
+ PIN(IN, gpg3-5, DOWN, LV1);
+ PIN(IN, gpg3-7, DOWN, LV1);
+ };
+};
+
+&pinctrl_touch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_touch>;
+
+ initial_touch: initial-state {
+ PIN(IN, gpj1-2, DOWN, LV1);
+ };
+};
+
+&pwm {
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&mic {
+ status = "okay";
+
+ i80-if-timings {
+ };
+};
+
+&pmu_system_controller {
+ assigned-clocks = <&pmu_system_controller 0>;
+ assigned-clock-parents = <&xxti>;
+};
+
+&serial_1 {
+ status = "okay";
+};
+
+&spi_1 {
+ cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ wm5110: wm5110-codec@0 {
+ compatible = "wlf,wm5110";
+ reg = <0x0>;
+ spi-max-frequency = <20000000>;
+ interrupt-parent = <&gpa0>;
+ interrupts = <4 IRQ_TYPE_NONE>;
+ clocks = <&pmu_system_controller 0>,
+ <&s2mps13_osc S2MPS11_CLK_BT>;
+ clock-names = "mclk1", "mclk2";
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ wlf,micd-detect-debounce = <300>;
+ wlf,micd-bias-start-time = <0x1>;
+ wlf,micd-rate = <0x7>;
+ wlf,micd-dbtime = <0x1>;
+ wlf,micd-force-micbias;
+ wlf,micd-configs = <0x0 1 0>;
+ wlf,hpdet-channel = <1>;
+ wlf,gpsw = <0x1>;
+ wlf,inmode = <2 0 2 0>;
+
+ wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+ wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+ /* core supplies */
+ AVDD-supply = <&ldo18_reg>;
+ DBVDD1-supply = <&ldo18_reg>;
+ CPVDD-supply = <&ldo18_reg>;
+ DBVDD2-supply = <&ldo18_reg>;
+ DBVDD3-supply = <&ldo18_reg>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <0>;
+ };
+ };
+};
+
+&timer {
+ clock-frequency = <24000000>;
+};
+
+&tmu_atlas0 {
+ vtmu-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&tmu_apollo {
+ vtmu-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&tmu_g3d {
+ vtmu-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&usbdrd30 {
+ vdd33-supply = <&ldo10_reg>;
+ vdd10-supply = <&ldo6_reg>;
+ status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "otg";
+};
+
+&usbdrd30_phy {
+ vbus-supply = <&safeout1_reg>;
+ status = "okay";
+};
+
+&xxti {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
new file mode 100644
index 000000000000..1db4e7f363a9
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
@@ -0,0 +1,41 @@
+/*
+ * SAMSUNG Exynos5433 TM2E board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Device tree source file for Samsung's TM2E(TM2 EDGE) board which is based on
+ * Samsung Exynos5433 SoC.
+ *
+ * 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 "exynos5433-tm2.dts"
+
+/ {
+ model = "Samsung TM2E board";
+ compatible = "samsung,tm2e", "samsung,exynos5433";
+};
+
+&ldo23_reg {
+ regulator-name = "CAM_SEN_CORE_1.025V_AP";
+ regulator-max-microvolt = <1050000>;
+};
+
+&ldo25_reg {
+ regulator-name = "UNUSED_LDO25";
+ regulator-always-off;
+};
+
+&ldo31_reg {
+ regulator-name = "TSP_VDD_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&ldo38_reg {
+ regulator-name = "VCC_3.3V_MOTOR_AP";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi
new file mode 100644
index 000000000000..9be2978f1b9a
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi
@@ -0,0 +1,23 @@
+/*
+ * Device tree sources for Exynos5433 TMU sensor configuration
+ *
+ * Copyright (c) 2016 Jonghwa Lee <jonghwa3.lee@samsung.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 <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <8>;
+samsung,tmu_reference_voltage = <23>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <75>;
+samsung,tmu_min_efuse_value = <40>;
+samsung,tmu_max_efuse_value = <150>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <85>;
+samsung,tmu_default_temp_offset = <50>;
+samsung,tmu_mux_addr = <6>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi
new file mode 100644
index 000000000000..125fe58d77ce
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi
@@ -0,0 +1,22 @@
+/*
+ * Device tree sources for Exynos5433 TMU sensor configuration
+ *
+ * Copyright (c) 2016 Chanwoo Choi <cw00.choi@samsung.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 <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <8>;
+samsung,tmu_reference_voltage = <16>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <75>;
+samsung,tmu_min_efuse_value = <40>;
+samsung,tmu_max_efuse_value = <150>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <85>;
+samsung,tmu_default_temp_offset = <50>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi
new file mode 100644
index 000000000000..ceaa05145b8a
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tmu.dtsi
@@ -0,0 +1,296 @@
+/*
+ * Device tree sources for Exynos5433 thermal zone
+ *
+ * Copyright (c) 2016 Chanwoo Choi <cw00.choi@samsung.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 <dt-bindings/thermal/thermal.h>
+
+/ {
+thermal-zones {
+ atlas0_thermal: atlas0-thermal {
+ thermal-sensors = <&tmu_atlas0>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ atlas0_alert_0: atlas0-alert-0 {
+ temperature = <65000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas0_alert_1: atlas0-alert-1 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas0_alert_2: atlas0-alert-2 {
+ temperature = <75000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas0_alert_3: atlas0-alert-3 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas0_alert_4: atlas0-alert-4 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas0_alert_5: atlas0-alert-5 {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas0_alert_6: atlas0-alert-6 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ /* Set maximum frequency as 1800MHz */
+ trip = <&atlas0_alert_0>;
+ cooling-device = <&cpu4 1 2>;
+ };
+ map1 {
+ /* Set maximum frequency as 1700MHz */
+ trip = <&atlas0_alert_1>;
+ cooling-device = <&cpu4 2 3>;
+ };
+ map2 {
+ /* Set maximum frequency as 1600MHz */
+ trip = <&atlas0_alert_2>;
+ cooling-device = <&cpu4 3 4>;
+ };
+ map3 {
+ /* Set maximum frequency as 1500MHz */
+ trip = <&atlas0_alert_3>;
+ cooling-device = <&cpu4 4 5>;
+ };
+ map4 {
+ /* Set maximum frequency as 1400MHz */
+ trip = <&atlas0_alert_4>;
+ cooling-device = <&cpu4 5 7>;
+ };
+ map5 {
+ /* Set maximum frequencyas 1200MHz */
+ trip = <&atlas0_alert_5>;
+ cooling-device = <&cpu4 7 9>;
+ };
+ map6 {
+ /* Set maximum frequency as 1000MHz */
+ trip = <&atlas0_alert_6>;
+ cooling-device = <&cpu4 9 14>;
+ };
+ };
+ };
+
+ atlas1_thermal: atlas1-thermal {
+ thermal-sensors = <&tmu_atlas1>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ atlas1_alert_0: atlas1-alert-0 {
+ temperature = <65000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas1_alert_1: atlas1-alert-1 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas1_alert_2: atlas1-alert-2 {
+ temperature = <75000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas1_alert_3: atlas1-alert-3 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas1_alert_4: atlas1-alert-4 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas1_alert_5: atlas1-alert-5 {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ atlas1_alert_6: atlas1-alert-6 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ };
+ };
+
+ g3d_thermal: g3d-thermal {
+ thermal-sensors = <&tmu_g3d>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ g3d_alert_0: g3d-alert-0 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ g3d_alert_1: g3d-alert-1 {
+ temperature = <75000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ g3d_alert_2: g3d-alert-2 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ g3d_alert_3: g3d-alert-3 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ g3d_alert_4: g3d-alert-4 {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ g3d_alert_5: g3d-alert-5 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ g3d_alert_6: g3d-alert-6 {
+ temperature = <100000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ };
+ };
+
+ apollo_thermal: apollo-thermal {
+ thermal-sensors = <&tmu_apollo>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ apollo_alert_0: apollo-alert-0 {
+ temperature = <65000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ apollo_alert_1: apollo-alert-1 {
+ temperature = <70000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ apollo_alert_2: apollo-alert-2 {
+ temperature = <75000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ apollo_alert_3: apollo-alert-3 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ apollo_alert_4: apollo-alert-4 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ apollo_alert_5: apollo-alert-5 {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ apollo_alert_6: apollo-alert-6 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ /* Set maximum frequency as 1200MHz */
+ trip = <&apollo_alert_2>;
+ cooling-device = <&cpu0 1 2>;
+ };
+ map1 {
+ /* Set maximum frequency as 1100MHz */
+ trip = <&apollo_alert_3>;
+ cooling-device = <&cpu0 2 3>;
+ };
+ map2 {
+ /* Set maximum frequency as 1000MHz */
+ trip = <&apollo_alert_4>;
+ cooling-device = <&cpu0 3 4>;
+ };
+ map3 {
+ /* Set maximum frequency as 900MHz */
+ trip = <&apollo_alert_5>;
+ cooling-device = <&cpu0 4 5>;
+ };
+ map4 {
+ /* Set maximum frequency as 800MHz */
+ trip = <&apollo_alert_6>;
+ cooling-device = <&cpu0 5 9>;
+ };
+ };
+ };
+
+ isp_thermal: isp-thermal {
+ thermal-sensors = <&tmu_isp>;
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ trips {
+ isp_alert_0: isp-alert-0 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ isp_alert_1: isp-alert-1 {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ isp_alert_2: isp-alert-2 {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ isp_alert_3: isp-alert-3 {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ isp_alert_4: isp-alert-4 {
+ temperature = <100000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ isp_alert_5: isp-alert-5 {
+ temperature = <105000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ isp_alert_6: isp-alert-6 {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <1000>; /* millicelsius */
+ type = "active";
+ };
+ };
+ };
+};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
new file mode 100644
index 000000000000..64226d5ae471
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -0,0 +1,1462 @@
+/*
+ * Samsung's Exynos5433 SoC device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Samsung's Exynos5433 SoC device nodes are listed in this file.
+ * Exynos5433 based board files can include this file and provide
+ * values for board specific bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos5433 SoC. As device tree coverage for Exynos5433 increases,
+ * additional nodes can be added to this file.
+ *
+ * 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/clock/exynos5433.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "samsung,exynos5433";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x100>;
+ clock-frequency = <1300000000>;
+ clocks = <&cmu_apollo CLK_SCLK_APOLLO>;
+ clock-names = "apolloclk";
+ operating-points-v2 = <&cluster_a53_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu1: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x101>;
+ clock-frequency = <1300000000>;
+ operating-points-v2 = <&cluster_a53_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu2: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x102>;
+ clock-frequency = <1300000000>;
+ operating-points-v2 = <&cluster_a53_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu3: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x103>;
+ clock-frequency = <1300000000>;
+ operating-points-v2 = <&cluster_a53_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu4: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x0>;
+ clock-frequency = <1900000000>;
+ clocks = <&cmu_atlas CLK_SCLK_ATLAS>;
+ clock-names = "atlasclk";
+ operating-points-v2 = <&cluster_a57_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu5: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x1>;
+ clock-frequency = <1900000000>;
+ operating-points-v2 = <&cluster_a57_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu6: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x2>;
+ clock-frequency = <1900000000>;
+ operating-points-v2 = <&cluster_a57_opp_table>;
+ #cooling-cells = <2>;
+ };
+
+ cpu7: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ enable-method = "psci";
+ reg = <0x3>;
+ clock-frequency = <1900000000>;
+ operating-points-v2 = <&cluster_a57_opp_table>;
+ #cooling-cells = <2>;
+ };
+ };
+
+ cluster_a53_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <900000>;
+ };
+ opp@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <925000>;
+ };
+ opp@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <950000>;
+ };
+ opp@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <975000>;
+ };
+ opp@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1000000>;
+ };
+ opp@900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = <1050000>;
+ };
+ opp@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1075000>;
+ };
+ opp@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-microvolt = <1112500>;
+ };
+ opp@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1112500>;
+ };
+ opp@1300000000 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <1150000>;
+ };
+ };
+
+ cluster_a57_opp_table: opp_table1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <900000>;
+ };
+ opp@600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <900000>;
+ };
+ opp@700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <912500>;
+ };
+ opp@800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <912500>;
+ };
+ opp@900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-microvolt = <937500>;
+ };
+ opp@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <975000>;
+ };
+ opp@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ opp-microvolt = <1012500>;
+ };
+ opp@1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1037500>;
+ };
+ opp@1300000000 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <1062500>;
+ };
+ opp@1400000000 {
+ opp-hz = /bits/ 64 <1400000000>;
+ opp-microvolt = <1087500>;
+ };
+ opp@1500000000 {
+ opp-hz = /bits/ 64 <1500000000>;
+ opp-microvolt = <1125000>;
+ };
+ opp@1600000000 {
+ opp-hz = /bits/ 64 <1600000000>;
+ opp-microvolt = <1137500>;
+ };
+ opp@1700000000 {
+ opp-hz = /bits/ 64 <1700000000>;
+ opp-microvolt = <1175000>;
+ };
+ opp@1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1212500>;
+ };
+ opp@1900000000 {
+ opp-hz = /bits/ 64 <1900000000>;
+ opp-microvolt = <1262500>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci";
+ method = "smc";
+ cpu_off = <0x84000002>;
+ cpu_on = <0xC4000003>;
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x400>; /* SWRESET */
+ mask = <0x1>;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x0 0x18000000>;
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ xxti: xxti {
+ compatible = "fixed-clock";
+ clock-output-names = "oscclk";
+ #clock-cells = <0>;
+ };
+
+ cmu_top: clock-controller@10030000 {
+ compatible = "samsung,exynos5433-cmu-top";
+ reg = <0x10030000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "sclk_mphy_pll",
+ "sclk_mfc_pll",
+ "sclk_bus_pll";
+ clocks = <&xxti>,
+ <&cmu_cpif CLK_SCLK_MPHY_PLL>,
+ <&cmu_mif CLK_SCLK_MFC_PLL>,
+ <&cmu_mif CLK_SCLK_BUS_PLL>;
+ };
+
+ cmu_cpif: clock-controller@10fc0000 {
+ compatible = "samsung,exynos5433-cmu-cpif";
+ reg = <0x10fc0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk";
+ clocks = <&xxti>;
+ };
+
+ cmu_mif: clock-controller@105b0000 {
+ compatible = "samsung,exynos5433-cmu-mif";
+ reg = <0x105b0000 0x2000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "sclk_mphy_pll";
+ clocks = <&xxti>,
+ <&cmu_cpif CLK_SCLK_MPHY_PLL>;
+ };
+
+ cmu_peric: clock-controller@14c80000 {
+ compatible = "samsung,exynos5433-cmu-peric";
+ reg = <0x14c80000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ cmu_peris: clock-controller@0x10040000 {
+ compatible = "samsung,exynos5433-cmu-peris";
+ reg = <0x10040000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ cmu_fsys: clock-controller@156e0000 {
+ compatible = "samsung,exynos5433-cmu-fsys";
+ reg = <0x156e0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "sclk_ufs_mphy",
+ "aclk_fsys_200",
+ "sclk_pcie_100_fsys",
+ "sclk_ufsunipro_fsys",
+ "sclk_mmc2_fsys",
+ "sclk_mmc1_fsys",
+ "sclk_mmc0_fsys",
+ "sclk_usbhost30_fsys",
+ "sclk_usbdrd30_fsys";
+ clocks = <&xxti>,
+ <&cmu_cpif CLK_SCLK_UFS_MPHY>,
+ <&cmu_top CLK_ACLK_FSYS_200>,
+ <&cmu_top CLK_SCLK_PCIE_100_FSYS>,
+ <&cmu_top CLK_SCLK_UFSUNIPRO_FSYS>,
+ <&cmu_top CLK_SCLK_MMC2_FSYS>,
+ <&cmu_top CLK_SCLK_MMC1_FSYS>,
+ <&cmu_top CLK_SCLK_MMC0_FSYS>,
+ <&cmu_top CLK_SCLK_USBHOST30_FSYS>,
+ <&cmu_top CLK_SCLK_USBDRD30_FSYS>;
+ };
+
+ cmu_g2d: clock-controller@12460000 {
+ compatible = "samsung,exynos5433-cmu-g2d";
+ reg = <0x12460000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "aclk_g2d_266",
+ "aclk_g2d_400";
+ clocks = <&xxti>,
+ <&cmu_top CLK_ACLK_G2D_266>,
+ <&cmu_top CLK_ACLK_G2D_400>;
+ };
+
+ cmu_disp: clock-controller@13b90000 {
+ compatible = "samsung,exynos5433-cmu-disp";
+ reg = <0x13b90000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "sclk_dsim1_disp",
+ "sclk_dsim0_disp",
+ "sclk_dsd_disp",
+ "sclk_decon_tv_eclk_disp",
+ "sclk_decon_vclk_disp",
+ "sclk_decon_eclk_disp",
+ "sclk_decon_tv_vclk_disp",
+ "aclk_disp_333";
+ clocks = <&xxti>,
+ <&cmu_mif CLK_SCLK_DSIM1_DISP>,
+ <&cmu_mif CLK_SCLK_DSIM0_DISP>,
+ <&cmu_mif CLK_SCLK_DSD_DISP>,
+ <&cmu_mif CLK_SCLK_DECON_TV_ECLK_DISP>,
+ <&cmu_mif CLK_SCLK_DECON_VCLK_DISP>,
+ <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>,
+ <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>,
+ <&cmu_mif CLK_ACLK_DISP_333>;
+ };
+
+ cmu_aud: clock-controller@114c0000 {
+ compatible = "samsung,exynos5433-cmu-aud";
+ reg = <0x114c0000 0x1000>;
+ #clock-cells = <1>;
+ clock-names = "oscclk", "fout_aud_pll";
+ clocks = <&xxti>, <&cmu_top CLK_FOUT_AUD_PLL>;
+ };
+
+ cmu_bus0: clock-controller@13600000 {
+ compatible = "samsung,exynos5433-cmu-bus0";
+ reg = <0x13600000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "aclk_bus0_400";
+ clocks = <&cmu_top CLK_ACLK_BUS0_400>;
+ };
+
+ cmu_bus1: clock-controller@14800000 {
+ compatible = "samsung,exynos5433-cmu-bus1";
+ reg = <0x14800000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "aclk_bus1_400";
+ clocks = <&cmu_top CLK_ACLK_BUS1_400>;
+ };
+
+ cmu_bus2: clock-controller@13400000 {
+ compatible = "samsung,exynos5433-cmu-bus2";
+ reg = <0x13400000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk", "aclk_bus2_400";
+ clocks = <&xxti>, <&cmu_mif CLK_ACLK_BUS2_400>;
+ };
+
+ cmu_g3d: clock-controller@14aa0000 {
+ compatible = "samsung,exynos5433-cmu-g3d";
+ reg = <0x14aa0000 0x2000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk", "aclk_g3d_400";
+ clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>;
+ };
+
+ cmu_gscl: clock-controller@13cf0000 {
+ compatible = "samsung,exynos5433-cmu-gscl";
+ reg = <0x13cf0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "aclk_gscl_111",
+ "aclk_gscl_333";
+ clocks = <&xxti>,
+ <&cmu_top CLK_ACLK_GSCL_111>,
+ <&cmu_top CLK_ACLK_GSCL_333>;
+ };
+
+ cmu_apollo: clock-controller@11900000 {
+ compatible = "samsung,exynos5433-cmu-apollo";
+ reg = <0x11900000 0x2000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk", "sclk_bus_pll_apollo";
+ clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_APOLLO>;
+ };
+
+ cmu_atlas: clock-controller@11800000 {
+ compatible = "samsung,exynos5433-cmu-atlas";
+ reg = <0x11800000 0x2000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk", "sclk_bus_pll_atlas";
+ clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_ATLAS>;
+ };
+
+ cmu_mscl: clock-controller@105d0000 {
+ compatible = "samsung,exynos5433-cmu-mscl";
+ reg = <0x150d0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "sclk_jpeg_mscl",
+ "aclk_mscl_400";
+ clocks = <&xxti>,
+ <&cmu_top CLK_SCLK_JPEG_MSCL>,
+ <&cmu_top CLK_ACLK_MSCL_400>;
+ };
+
+ cmu_mfc: clock-controller@15280000 {
+ compatible = "samsung,exynos5433-cmu-mfc";
+ reg = <0x15280000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk", "aclk_mfc_400";
+ clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>;
+ };
+
+ cmu_hevc: clock-controller@14f80000 {
+ compatible = "samsung,exynos5433-cmu-hevc";
+ reg = <0x14f80000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk", "aclk_hevc_400";
+ clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>;
+ };
+
+ cmu_isp: clock-controller@146d0000 {
+ compatible = "samsung,exynos5433-cmu-isp";
+ reg = <0x146d0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "aclk_isp_dis_400",
+ "aclk_isp_400";
+ clocks = <&xxti>,
+ <&cmu_top CLK_ACLK_ISP_DIS_400>,
+ <&cmu_top CLK_ACLK_ISP_400>;
+ };
+
+ cmu_cam0: clock-controller@120d0000 {
+ compatible = "samsung,exynos5433-cmu-cam0";
+ reg = <0x120d0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "aclk_cam0_333",
+ "aclk_cam0_400",
+ "aclk_cam0_552";
+ clocks = <&xxti>,
+ <&cmu_top CLK_ACLK_CAM0_333>,
+ <&cmu_top CLK_ACLK_CAM0_400>,
+ <&cmu_top CLK_ACLK_CAM0_552>;
+ };
+
+ cmu_cam1: clock-controller@145d0000 {
+ compatible = "samsung,exynos5433-cmu-cam1";
+ reg = <0x145d0000 0x1000>;
+ #clock-cells = <1>;
+
+ clock-names = "oscclk",
+ "sclk_isp_uart_cam1",
+ "sclk_isp_spi1_cam1",
+ "sclk_isp_spi0_cam1",
+ "aclk_cam1_333",
+ "aclk_cam1_400",
+ "aclk_cam1_552";
+ clocks = <&xxti>,
+ <&cmu_top CLK_SCLK_ISP_UART_CAM1>,
+ <&cmu_top CLK_SCLK_ISP_SPI1_CAM1>,
+ <&cmu_top CLK_SCLK_ISP_SPI0_CAM1>,
+ <&cmu_top CLK_ACLK_CAM1_333>,
+ <&cmu_top CLK_ACLK_CAM1_400>,
+ <&cmu_top CLK_ACLK_CAM1_552>;
+ };
+
+ tmu_atlas0: tmu@10060000 {
+ compatible = "samsung,exynos5433-tmu";
+ reg = <0x10060000 0x200>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peris CLK_PCLK_TMU0_APBIF>,
+ <&cmu_peris CLK_SCLK_TMU0>;
+ clock-names = "tmu_apbif", "tmu_sclk";
+ #include "exynos5433-tmu-sensor-conf.dtsi"
+ status = "disabled";
+ };
+
+ tmu_atlas1: tmu@10068000 {
+ compatible = "samsung,exynos5433-tmu";
+ reg = <0x10068000 0x200>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peris CLK_PCLK_TMU0_APBIF>,
+ <&cmu_peris CLK_SCLK_TMU0>;
+ clock-names = "tmu_apbif", "tmu_sclk";
+ #include "exynos5433-tmu-sensor-conf.dtsi"
+ status = "disabled";
+ };
+
+ tmu_g3d: tmu@10070000 {
+ compatible = "samsung,exynos5433-tmu";
+ reg = <0x10070000 0x200>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
+ <&cmu_peris CLK_SCLK_TMU1>;
+ clock-names = "tmu_apbif", "tmu_sclk";
+ #include "exynos5433-tmu-g3d-sensor-conf.dtsi"
+ status = "disabled";
+ };
+
+ tmu_apollo: tmu@10078000 {
+ compatible = "samsung,exynos5433-tmu";
+ reg = <0x10078000 0x200>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
+ <&cmu_peris CLK_SCLK_TMU1>;
+ clock-names = "tmu_apbif", "tmu_sclk";
+ #include "exynos5433-tmu-sensor-conf.dtsi"
+ status = "disabled";
+ };
+
+ tmu_isp: tmu@1007c000 {
+ compatible = "samsung,exynos5433-tmu";
+ reg = <0x1007c000 0x200>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
+ <&cmu_peris CLK_SCLK_TMU1>;
+ clock-names = "tmu_apbif", "tmu_sclk";
+ #include "exynos5433-tmu-sensor-conf.dtsi"
+ status = "disabled";
+ };
+
+ mct@101c0000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x101c0000 0x800>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <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>;
+ clocks = <&xxti>, <&cmu_peris CLK_PCLK_MCT>;
+ clock-names = "fin_pll", "mct";
+ };
+
+ pinctrl_alive: pinctrl@10580000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos7-wakeup-eint";
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ pinctrl_aud: pinctrl@114b0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x114b0000 0x1000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_cpif: pinctrl@10fe0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x10fe0000 0x1000>;
+ interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_ese: pinctrl@14ca0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x14ca0000 0x1000>;
+ interrupts = <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_finger: pinctrl@14cb0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x14cb0000 0x1000>;
+ interrupts = <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_fsys: pinctrl@15690000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x15690000 0x1000>;
+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_imem: pinctrl@11090000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x11090000 0x1000>;
+ interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_nfc: pinctrl@14cd0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x14cd0000 0x1000>;
+ interrupts = <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_peric: pinctrl@14cc0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x14cc0000 0x1100>;
+ interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_touch: pinctrl@14ce0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x14ce0000 0x1100>;
+ interrupts = <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pmu_system_controller: system-controller@105c0000 {
+ compatible = "samsung,exynos5433-pmu", "syscon";
+ reg = <0x105c0000 0x5008>;
+ #clock-cells = <1>;
+ clock-names = "clkout16";
+ clocks = <&xxti>;
+ };
+
+ gic: interrupt-controller@11001000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x11001000 0x1000>,
+ <0x11002000 0x2000>,
+ <0x11004000 0x2000>,
+ <0x11006000 0x2000>;
+ interrupts = <GIC_PPI 9 0xf04>;
+ };
+
+ mipi_phy: video-phy@105c0710 {
+ compatible = "samsung,exynos5433-mipi-video-phy";
+ #phy-cells = <1>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ samsung,cam0-sysreg = <&syscon_cam0>;
+ samsung,cam1-sysreg = <&syscon_cam1>;
+ samsung,disp-sysreg = <&syscon_disp>;
+ };
+
+ decon: decon@13800000 {
+ compatible = "samsung,exynos5433-decon";
+ reg = <0x13800000 0x2104>;
+ clocks = <&cmu_disp CLK_PCLK_DECON>,
+ <&cmu_disp CLK_ACLK_DECON>,
+ <&cmu_disp CLK_ACLK_SMMU_DECON0X>,
+ <&cmu_disp CLK_ACLK_XIU_DECON0X>,
+ <&cmu_disp CLK_PCLK_SMMU_DECON0X>,
+ <&cmu_disp CLK_SCLK_DECON_VCLK>,
+ <&cmu_disp CLK_SCLK_DECON_ECLK>;
+ clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x",
+ "aclk_xiu_decon0x", "pclk_smmu_decon0x",
+ "sclk_decon_vclk", "sclk_decon_eclk";
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
+ samsung,disp-sysreg = <&syscon_disp>;
+ status = "disabled";
+ iommus = <&sysmmu_decon0x>, <&sysmmu_decon1x>;
+ iommu-names = "m0", "m1";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ decon_to_mic: endpoint {
+ remote-endpoint =
+ <&mic_to_decon>;
+ };
+ };
+ };
+ };
+
+ dsi: dsi@13900000 {
+ compatible = "samsung,exynos5433-mipi-dsi";
+ reg = <0x13900000 0xC0>;
+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&mipi_phy 1>;
+ phy-names = "dsim";
+ clocks = <&cmu_disp CLK_PCLK_DSIM0>,
+ <&cmu_disp CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8>,
+ <&cmu_disp CLK_PHYCLK_MIPIDPHY0_RXCLKESC0>,
+ <&cmu_disp CLK_SCLK_RGB_VCLK_TO_DSIM0>,
+ <&cmu_disp CLK_SCLK_DSIM0>;
+ clock-names = "bus_clk",
+ "phyclk_mipidphy0_bitclkdiv8",
+ "phyclk_mipidphy0_rxclkesc0",
+ "sclk_rgb_vclk_to_dsim0",
+ "sclk_mipi";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi_to_mic: endpoint {
+ remote-endpoint = <&mic_to_dsi>;
+ };
+ };
+ };
+ };
+
+ mic: mic@13930000 {
+ compatible = "samsung,exynos5433-mic";
+ reg = <0x13930000 0x48>;
+ clocks = <&cmu_disp CLK_PCLK_MIC0>,
+ <&cmu_disp CLK_SCLK_RGB_VCLK_TO_MIC0>;
+ clock-names = "pclk_mic0", "sclk_rgb_vclk_to_mic0";
+ samsung,disp-syscon = <&syscon_disp>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mic_to_decon: endpoint {
+ remote-endpoint =
+ <&decon_to_mic>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ mic_to_dsi: endpoint {
+ remote-endpoint = <&dsi_to_mic>;
+ };
+ };
+ };
+ };
+
+ syscon_disp: syscon@13b80000 {
+ compatible = "syscon";
+ reg = <0x13b80000 0x1010>;
+ };
+
+ syscon_cam0: syscon@120f0000 {
+ compatible = "syscon";
+ reg = <0x120f0000 0x1020>;
+ };
+
+ syscon_cam1: syscon@145f0000 {
+ compatible = "syscon";
+ reg = <0x145f0000 0x1038>;
+ };
+
+ gsc_0: video-scaler@13C00000 {
+ compatible = "samsung,exynos5433-gsc";
+ reg = <0x13c00000 0x1000>;
+ interrupts = <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk", "aclk_xiu",
+ "aclk_gsclbend";
+ clocks = <&cmu_gscl CLK_PCLK_GSCL0>,
+ <&cmu_gscl CLK_ACLK_GSCL0>,
+ <&cmu_gscl CLK_ACLK_XIU_GSCLX>,
+ <&cmu_gscl CLK_ACLK_GSCLBEND_333>;
+ iommus = <&sysmmu_gscl0>;
+ };
+
+ gsc_1: video-scaler@13C10000 {
+ compatible = "samsung,exynos5433-gsc";
+ reg = <0x13c10000 0x1000>;
+ interrupts = <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk", "aclk_xiu",
+ "aclk_gsclbend";
+ clocks = <&cmu_gscl CLK_PCLK_GSCL1>,
+ <&cmu_gscl CLK_ACLK_GSCL1>,
+ <&cmu_gscl CLK_ACLK_XIU_GSCLX>,
+ <&cmu_gscl CLK_ACLK_GSCLBEND_333>;
+ iommus = <&sysmmu_gscl1>;
+ };
+
+ gsc_2: video-scaler@13C20000 {
+ compatible = "samsung,exynos5433-gsc";
+ reg = <0x13c20000 0x1000>;
+ interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk", "aclk_xiu",
+ "aclk_gsclbend";
+ clocks = <&cmu_gscl CLK_PCLK_GSCL2>,
+ <&cmu_gscl CLK_ACLK_GSCL2>,
+ <&cmu_gscl CLK_ACLK_XIU_GSCLX>,
+ <&cmu_gscl CLK_ACLK_GSCLBEND_333>;
+ iommus = <&sysmmu_gscl2>;
+ };
+
+ jpeg: codec@15020000 {
+ compatible = "samsung,exynos5433-jpeg";
+ reg = <0x15020000 0x10000>;
+ interrupts = <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk", "aclk_xiu", "sclk";
+ clocks = <&cmu_mscl CLK_PCLK_JPEG>,
+ <&cmu_mscl CLK_ACLK_JPEG>,
+ <&cmu_mscl CLK_ACLK_XIU_MSCLX>,
+ <&cmu_mscl CLK_SCLK_JPEG>;
+ iommus = <&sysmmu_jpeg>;
+ };
+
+ mfc: codec@152E0000 {
+ compatible = "samsung,exynos5433-mfc";
+ reg = <0x152E0000 0x10000>;
+ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk", "aclk_xiu";
+ clocks = <&cmu_mfc CLK_PCLK_MFC>,
+ <&cmu_mfc CLK_ACLK_MFC>,
+ <&cmu_mfc CLK_ACLK_XIU_MFCX>;
+ iommus = <&sysmmu_mfc_0>, <&sysmmu_mfc_1>;
+ iommu-names = "left", "right";
+ };
+
+ sysmmu_decon0x: sysmmu@0x13a00000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13a00000 0x1000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk";
+ clocks = <&cmu_disp CLK_PCLK_SMMU_DECON0X>,
+ <&cmu_disp CLK_ACLK_SMMU_DECON0X>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_decon1x: sysmmu@0x13a10000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13a10000 0x1000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk";
+ clocks = <&cmu_disp CLK_PCLK_SMMU_DECON1X>,
+ <&cmu_disp CLK_ACLK_SMMU_DECON1X>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_gscl0: sysmmu@0x13C80000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13C80000 0x1000>;
+ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "aclk", "pclk";
+ clocks = <&cmu_gscl CLK_ACLK_SMMU_GSCL0>,
+ <&cmu_gscl CLK_PCLK_SMMU_GSCL0>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_gscl1: sysmmu@0x13C90000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13C90000 0x1000>;
+ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "aclk", "pclk";
+ clocks = <&cmu_gscl CLK_ACLK_SMMU_GSCL1>,
+ <&cmu_gscl CLK_PCLK_SMMU_GSCL1>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_gscl2: sysmmu@0x13CA0000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x13CA0000 0x1000>;
+ interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "aclk", "pclk";
+ clocks = <&cmu_gscl CLK_ACLK_SMMU_GSCL2>,
+ <&cmu_gscl CLK_PCLK_SMMU_GSCL2>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_jpeg: sysmmu@0x15060000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x15060000 0x1000>;
+ interrupts = <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk";
+ clocks = <&cmu_mscl CLK_PCLK_SMMU_JPEG>,
+ <&cmu_mscl CLK_ACLK_SMMU_JPEG>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_mfc_0: sysmmu@0x15200000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x15200000 0x1000>;
+ interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk";
+ clocks = <&cmu_mfc CLK_PCLK_SMMU_MFC_0>,
+ <&cmu_mfc CLK_ACLK_SMMU_MFC_0>;
+ #iommu-cells = <0>;
+ };
+
+ sysmmu_mfc_1: sysmmu@0x15210000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x15210000 0x1000>;
+ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "pclk", "aclk";
+ clocks = <&cmu_mfc CLK_PCLK_SMMU_MFC_1>,
+ <&cmu_mfc CLK_ACLK_SMMU_MFC_1>;
+ #iommu-cells = <0>;
+ };
+
+ serial_0: serial@14c10000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x14c10000 0x100>;
+ interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peric CLK_PCLK_UART0>,
+ <&cmu_peric CLK_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_bus>;
+ status = "disabled";
+ };
+
+ serial_1: serial@14c20000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x14c20000 0x100>;
+ interrupts = <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peric CLK_PCLK_UART1>,
+ <&cmu_peric CLK_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_bus>;
+ status = "disabled";
+ };
+
+ serial_2: serial@14c30000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x14c30000 0x100>;
+ interrupts = <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peric CLK_PCLK_UART2>,
+ <&cmu_peric CLK_SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_bus>;
+ status = "disabled";
+ };
+
+ spi_0: spi@14d20000 {
+ compatible = "samsung,exynos5433-spi";
+ reg = <0x14d20000 0x100>;
+ interrupts = <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 9>, <&pdma0 8>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric CLK_PCLK_SPI0>,
+ <&cmu_peric CLK_SCLK_SPI0>,
+ <&cmu_peric CLK_SCLK_IOCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0", "spi_ioclk";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ spi_1: spi@14d30000 {
+ compatible = "samsung,exynos5433-spi";
+ reg = <0x14d30000 0x100>;
+ interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 11>, <&pdma0 10>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric CLK_PCLK_SPI1>,
+ <&cmu_peric CLK_SCLK_SPI1>,
+ <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0", "spi_ioclk";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ spi_2: spi@14d40000 {
+ compatible = "samsung,exynos5433-spi";
+ reg = <0x14d40000 0x100>;
+ interrupts = <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 13>, <&pdma0 12>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric CLK_PCLK_SPI2>,
+ <&cmu_peric CLK_SCLK_SPI2>,
+ <&cmu_peric CLK_SCLK_IOCLK_SPI2>;
+ clock-names = "spi", "spi_busclk0", "spi_ioclk";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ spi_3: spi@14d50000 {
+ compatible = "samsung,exynos5433-spi";
+ reg = <0x14d50000 0x100>;
+ interrupts = <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 23>, <&pdma0 22>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric CLK_PCLK_SPI3>,
+ <&cmu_peric CLK_SCLK_SPI3>,
+ <&cmu_peric CLK_SCLK_IOCLK_SPI3>;
+ clock-names = "spi", "spi_busclk0", "spi_ioclk";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi3_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ spi_4: spi@14d00000 {
+ compatible = "samsung,exynos5433-spi";
+ reg = <0x14d00000 0x100>;
+ interrupts = <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 25>, <&pdma0 24>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric CLK_PCLK_SPI4>,
+ <&cmu_peric CLK_SCLK_SPI4>,
+ <&cmu_peric CLK_SCLK_IOCLK_SPI4>;
+ clock-names = "spi", "spi_busclk0", "spi_ioclk";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi4_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ adc: adc@14d10000 {
+ compatible = "samsung,exynos7-adc";
+ reg = <0x14d10000 0x100>;
+ interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "adc";
+ clocks = <&cmu_peric CLK_PCLK_ADCIF>;
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ status = "disabled";
+ };
+
+ pwm: pwm@14dd0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x14dd0000 0x100>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ clocks = <&cmu_peric CLK_PCLK_PWM>;
+ clock-names = "timers";
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ hsi2c_0: hsi2c@14e40000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e40000 0x1000>;
+ interrupts = <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c0_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C0>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_1: hsi2c@14e50000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e50000 0x1000>;
+ interrupts = <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c1_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C1>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_2: hsi2c@14e60000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e60000 0x1000>;
+ interrupts = <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c2_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C2>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_3: hsi2c@14e70000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e70000 0x1000>;
+ interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c3_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C3>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_4: hsi2c@14ec0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14ec0000 0x1000>;
+ interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c4_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C4>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_5: hsi2c@14ed0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14ed0000 0x1000>;
+ interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c5_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C5>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_6: hsi2c@14ee0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14ee0000 0x1000>;
+ interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c6_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C6>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_7: hsi2c@14ef0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14ef0000 0x1000>;
+ interrupts = <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c7_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C7>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_8: hsi2c@14d90000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14d90000 0x1000>;
+ interrupts = <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c8_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C8>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_9: hsi2c@14da0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14da0000 0x1000>;
+ interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c9_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C9>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_10: hsi2c@14de0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14de0000 0x1000>;
+ interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c10_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C10>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_11: hsi2c@14df0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14df0000 0x1000>;
+ interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c11_bus>;
+ clocks = <&cmu_peric CLK_PCLK_HSI2C11>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ usbdrd30: usb@15400000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ clocks = <&cmu_fsys CLK_ACLK_USBDRD30>,
+ <&cmu_fsys CLK_SCLK_USBDRD30>;
+ clock-names = "usbdrd30", "usbdrd30_susp_clk";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ dwc3@15400000 {
+ compatible = "snps,dwc3";
+ reg = <0x15400000 0x10000>;
+ interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usbdrd30_phy 0>, <&usbdrd30_phy 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
+ usbdrd30_phy: phy@15500000 {
+ compatible = "samsung,exynos5433-usbdrd-phy";
+ reg = <0x15500000 0x100>;
+ clocks = <&cmu_fsys CLK_ACLK_USBDRD30>, <&xxti>,
+ <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK>,
+ <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK>,
+ <&cmu_fsys CLK_SCLK_USBDRD30>;
+ clock-names = "phy", "ref", "phy_utmi", "phy_pipe",
+ "itp";
+ #phy-cells = <1>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ usbhost30_phy: phy@15580000 {
+ compatible = "samsung,exynos5433-usbdrd-phy";
+ reg = <0x15580000 0x100>;
+ clocks = <&cmu_fsys CLK_ACLK_USBHOST30>, <&xxti>,
+ <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK>,
+ <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK>,
+ <&cmu_fsys CLK_SCLK_USBHOST30>;
+ clock-names = "phy", "ref", "phy_utmi", "phy_pipe",
+ "itp";
+ #phy-cells = <1>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ usbhost30: usb@15a00000 {
+ compatible = "samsung,exynos5250-dwusb3";
+ clocks = <&cmu_fsys CLK_ACLK_USBHOST30>,
+ <&cmu_fsys CLK_SCLK_USBHOST30>;
+ clock-names = "usbdrd30", "usbdrd30_susp_clk";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+
+ usbdrd_dwc3_0: dwc3@15a00000 {
+ compatible = "snps,dwc3";
+ reg = <0x15a00000 0x10000>;
+ interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usbhost30_phy 0>, <&usbhost30_phy 1>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
+ mshc_0: mshc@15540000 {
+ compatible = "samsung,exynos7-dw-mshc-smu";
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x15540000 0x2000>;
+ clocks = <&cmu_fsys CLK_ACLK_MMC0>,
+ <&cmu_fsys CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mshc_1: mshc@15550000 {
+ compatible = "samsung,exynos7-dw-mshc-smu";
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x15550000 0x2000>;
+ clocks = <&cmu_fsys CLK_ACLK_MMC1>,
+ <&cmu_fsys CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mshc_2: mshc@15560000 {
+ compatible = "samsung,exynos7-dw-mshc-smu";
+ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x15560000 0x2000>;
+ clocks = <&cmu_fsys CLK_ACLK_MMC2>,
+ <&cmu_fsys CLK_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma0: pdma@15610000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x15610000 0x1000>;
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_fsys CLK_PDMA0>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ pdma1: pdma@15600000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x15600000 0x1000>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_fsys CLK_PDMA1>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+ };
+
+ audio-subsystem@11400000 {
+ compatible = "samsung,exynos5433-lpass";
+ reg = <0x11400000 0x100>, <0x11500000 0x08>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ adma: adma@11420000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x11420000 0x1000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_aud CLK_ACLK_DMAC>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ };
+
+ i2s0: i2s0@11440000 {
+ compatible = "samsung,exynos7-i2s";
+ reg = <0x11440000 0x100>;
+ dmas = <&adma 0 &adma 2>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
+ <&cmu_aud CLK_SCLK_AUD_I2S>,
+ <&cmu_aud CLK_SCLK_I2S_BCLK>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ status = "disabled";
+ };
+
+ serial_3: serial@11460000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x11460000 0x100>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
+ <&cmu_aud CLK_SCLK_AUD_UART>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_aud_bus>;
+ status = "disabled";
+ };
+ };
+ };
+
+ timer: timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+};
+
+#include "exynos5433-pinctrl.dtsi"
+#include "exynos5433-tmu.dtsi"
diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
index f77ddaf21d04..82321984e1fb 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -20,8 +20,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
#interrupt-cells = <2>;
- interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
- <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
gpa1: gpa1 {
@@ -31,8 +37,14 @@
interrupt-controller;
interrupt-parent = <&gic>;
#interrupt-cells = <2>;
- interrupts = <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
- <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
};
gpa2: gpa2 {
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 6328a66ed97e..80aa60e38237 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -35,28 +35,28 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu_atlas0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0x0>;
enable-method = "psci";
};
- cpu@1 {
+ cpu_atlas1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0x1>;
enable-method = "psci";
};
- cpu@2 {
+ cpu_atlas2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0x2>;
enable-method = "psci";
};
- cpu@3 {
+ cpu_atlas3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0x3>;
@@ -106,7 +106,7 @@
pdma0: pdma@10E10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10E10000 0x1000>;
- interrupts = <0 225 0>;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_fsys0 ACLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -117,7 +117,7 @@
pdma1: pdma@10EB0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10EB0000 0x1000>;
- interrupts = <0 226 0>;
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_fsys0 ACLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
@@ -220,7 +220,7 @@
serial_0: serial@13630000 {
compatible = "samsung,exynos4210-uart";
reg = <0x13630000 0x100>;
- interrupts = <0 440 0>;
+ interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peric0 PCLK_UART0>,
<&clock_peric0 SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
@@ -230,7 +230,7 @@
serial_1: serial@14c20000 {
compatible = "samsung,exynos4210-uart";
reg = <0x14c20000 0x100>;
- interrupts = <0 456 0>;
+ interrupts = <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peric1 PCLK_UART1>,
<&clock_peric1 SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0";
@@ -240,7 +240,7 @@
serial_2: serial@14c30000 {
compatible = "samsung,exynos4210-uart";
reg = <0x14c30000 0x100>;
- interrupts = <0 457 0>;
+ interrupts = <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peric1 PCLK_UART2>,
<&clock_peric1 SCLK_UART2>;
clock-names = "uart", "clk_uart_baud0";
@@ -250,7 +250,7 @@
serial_3: serial@14c40000 {
compatible = "samsung,exynos4210-uart";
reg = <0x14c40000 0x100>;
- interrupts = <0 458 0>;
+ interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peric1 PCLK_UART3>,
<&clock_peric1 SCLK_UART3>;
clock-names = "uart", "clk_uart_baud0";
@@ -264,62 +264,62 @@
wakeup-interrupt-controller {
compatible = "samsung,exynos7-wakeup-eint";
interrupt-parent = <&gic>;
- interrupts = <0 16 0>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
};
};
pinctrl_bus0: pinctrl@13470000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x13470000 0x1000>;
- interrupts = <0 383 0>;
+ interrupts = <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_nfc: pinctrl@14cd0000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x14cd0000 0x1000>;
- interrupts = <0 473 0>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_touch: pinctrl@14ce0000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x14ce0000 0x1000>;
- interrupts = <0 474 0>;
+ interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_ff: pinctrl@14c90000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x14c90000 0x1000>;
- interrupts = <0 475 0>;
+ interrupts = <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_ese: pinctrl@14ca0000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x14ca0000 0x1000>;
- interrupts = <0 476 0>;
+ interrupts = <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_fsys0: pinctrl@10e60000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x10e60000 0x1000>;
- interrupts = <0 221 0>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_fsys1: pinctrl@15690000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x15690000 0x1000>;
- interrupts = <0 203 0>;
+ interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
};
pinctrl_bus1: pinctrl@14870000 {
compatible = "samsung,exynos7-pinctrl";
reg = <0x14870000 0x1000>;
- interrupts = <0 384 0>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
};
hsi2c_0: hsi2c@13640000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13640000 0x1000>;
- interrupts = <0 441 0>;
+ interrupts = <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -332,7 +332,7 @@
hsi2c_1: hsi2c@13650000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13650000 0x1000>;
- interrupts = <0 442 0>;
+ interrupts = <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -345,7 +345,7 @@
hsi2c_2: hsi2c@14e60000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x14e60000 0x1000>;
- interrupts = <0 459 0>;
+ interrupts = <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -358,7 +358,7 @@
hsi2c_3: hsi2c@14e70000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x14e70000 0x1000>;
- interrupts = <0 460 0>;
+ interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -371,7 +371,7 @@
hsi2c_4: hsi2c@13660000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13660000 0x1000>;
- interrupts = <0 443 0>;
+ interrupts = <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -384,7 +384,7 @@
hsi2c_5: hsi2c@13670000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13670000 0x1000>;
- interrupts = <0 444 0>;
+ interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -397,7 +397,7 @@
hsi2c_6: hsi2c@14e00000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x14e00000 0x1000>;
- interrupts = <0 461 0>;
+ interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -410,7 +410,7 @@
hsi2c_7: hsi2c@13e10000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13e10000 0x1000>;
- interrupts = <0 462 0>;
+ interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -423,7 +423,7 @@
hsi2c_8: hsi2c@14e20000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x14e20000 0x1000>;
- interrupts = <0 463 0>;
+ interrupts = <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -436,7 +436,7 @@
hsi2c_9: hsi2c@13680000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13680000 0x1000>;
- interrupts = <0 445 0>;
+ interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -449,7 +449,7 @@
hsi2c_10: hsi2c@13690000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13690000 0x1000>;
- interrupts = <0 446 0>;
+ interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -462,7 +462,7 @@
hsi2c_11: hsi2c@136a0000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x136a0000 0x1000>;
- interrupts = <0 447 0>;
+ interrupts = <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
@@ -472,6 +472,16 @@
status = "disabled";
};
+ arm-pmu {
+ compatible = "arm,cortex-a57-pmu", "arm,armv8-pmuv3";
+ interrupts = <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>;
+ interrupt-affinity = <&cpu_atlas0>, <&cpu_atlas1>,
+ <&cpu_atlas2>, <&cpu_atlas3>;
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
@@ -499,7 +509,8 @@
rtc: rtc@10590000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x10590000 0x100>;
- interrupts = <0 355 0>, <0 356 0>;
+ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_ccore PCLK_RTC>;
clock-names = "rtc";
status = "disabled";
@@ -508,7 +519,7 @@
watchdog: watchdog@101d0000 {
compatible = "samsung,exynos7-wdt";
reg = <0x101d0000 0x100>;
- interrupts = <0 110 0>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peris PCLK_WDT>;
clock-names = "watchdog";
samsung,syscon-phandle = <&pmu_system_controller>;
@@ -517,7 +528,7 @@
mmc_0: mmc@15740000 {
compatible = "samsung,exynos7-dw-mshc-smu";
- interrupts = <0 201 0>;
+ interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x15740000 0x2000>;
@@ -530,7 +541,7 @@
mmc_1: mmc@15750000 {
compatible = "samsung,exynos7-dw-mshc";
- interrupts = <0 202 0>;
+ interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x15750000 0x2000>;
@@ -543,7 +554,7 @@
mmc_2: mmc@15560000 {
compatible = "samsung,exynos7-dw-mshc-smu";
- interrupts = <0 216 0>;
+ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x15560000 0x2000>;
@@ -557,7 +568,7 @@
adc: adc@13620000 {
compatible = "samsung,exynos7-adc";
reg = <0x13620000 0x100>;
- interrupts = <0 448 0>;
+ interrupts = <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peric0 PCLK_ADCIF>;
clock-names = "adc";
#io-channel-cells = <1>;
@@ -577,7 +588,7 @@
tmuctrl_0: tmu@10060000 {
compatible = "samsung,exynos7-tmu";
reg = <0x10060000 0x200>;
- interrupts = <0 108 0>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock_peris PCLK_TMU>,
<&clock_peris SCLK_TMU>;
clock-names = "tmu_apbif", "tmu_sclk";
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 1b7783db7de4..66027181fba4 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -1,5 +1,7 @@
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
index dd9e91941df4..0989d635b558 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
@@ -45,7 +45,7 @@
*/
/dts-v1/;
-/include/ "fsl-ls1043a.dtsi"
+#include "fsl-ls1043a.dtsi"
/ {
model = "LS1043A QDS Board";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
index d2313e05fd22..c37110bc1506 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
@@ -45,7 +45,7 @@
*/
/dts-v1/;
-/include/ "fsl-ls1043a.dtsi"
+#include "fsl-ls1043a.dtsi"
/ {
model = "LS1043A RDB Board";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index 97d331ec2500..ec13a6ecb754 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -44,6 +44,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <dt-bindings/thermal/thermal.h>
+
/ {
compatible = "fsl,ls1043a";
interrupt-parent = <&gic>;
@@ -66,6 +68,7 @@
reg = <0x0>;
clocks = <&clockgen 1 0>;
next-level-cache = <&l2>;
+ #cooling-cells = <2>;
};
cpu1: cpu@1 {
@@ -255,6 +258,81 @@
big-endian;
};
+ tmu: tmu@1f00000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0x0 0x1f00000 0x0 0x10000>;
+ interrupts = <0 33 0x4>;
+ fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>;
+ fsl,tmu-calibration = <0x00000000 0x00000026
+ 0x00000001 0x0000002d
+ 0x00000002 0x00000032
+ 0x00000003 0x00000039
+ 0x00000004 0x0000003f
+ 0x00000005 0x00000046
+ 0x00000006 0x0000004d
+ 0x00000007 0x00000054
+ 0x00000008 0x0000005a
+ 0x00000009 0x00000061
+ 0x0000000a 0x0000006a
+ 0x0000000b 0x00000071
+
+ 0x00010000 0x00000025
+ 0x00010001 0x0000002c
+ 0x00010002 0x00000035
+ 0x00010003 0x0000003d
+ 0x00010004 0x00000045
+ 0x00010005 0x0000004e
+ 0x00010006 0x00000057
+ 0x00010007 0x00000061
+ 0x00010008 0x0000006b
+ 0x00010009 0x00000076
+
+ 0x00020000 0x00000029
+ 0x00020001 0x00000033
+ 0x00020002 0x0000003d
+ 0x00020003 0x00000049
+ 0x00020004 0x00000056
+ 0x00020005 0x00000061
+ 0x00020006 0x0000006d
+
+ 0x00030000 0x00000021
+ 0x00030001 0x0000002a
+ 0x00030002 0x0000003c
+ 0x00030003 0x0000004e>;
+ #thermal-sensor-cells = <1>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+
+ thermal-sensors = <&tmu 3>;
+
+ trips {
+ cpu_alert: cpu-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit: cpu-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
dspi0: dspi@2100000 {
compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
new file mode 100644
index 000000000000..290e5b014414
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
@@ -0,0 +1,212 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1046A family SoC.
+ *
+ * Copyright 2016, Freescale Semiconductor, Inc.
+ *
+ * Shaohui Xie <Shaohui.Xie@nxp.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-ls1046a.dtsi"
+
+/ {
+ model = "LS1046A QDS Board";
+ compatible = "fsl,ls1046a-qds", "fsl,ls1046a";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ serial0 = &duart0;
+ serial1 = &duart1;
+ serial2 = &duart2;
+ serial3 = &duart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&dspi {
+ bus-num = <0>;
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a11", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+
+ flash@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst25wf040b", "jedec,spi-nor";
+ spi-cpol;
+ spi-cpha;
+ reg = <1>;
+ spi-max-frequency = <10000000>;
+ };
+
+ flash@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "en25s64", "jedec,spi-nor";
+ spi-cpol;
+ spi-cpha;
+ reg = <2>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
+&duart0 {
+ status = "okay";
+};
+
+&duart1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ pca9547@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ rtc@51 {
+ compatible = "nxp,pcf2129";
+ reg = <0x51>;
+ /* IRQ10_B */
+ interrupts = <0 150 0x4>;
+ };
+
+ eeprom@56 {
+ compatible = "atmel,24c512";
+ reg = <0x56>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c512";
+ reg = <0x57>;
+ };
+
+ temp-sensor@4c {
+ compatible = "adi,adt7461a";
+ reg = <0x4c>;
+ };
+ };
+ };
+};
+
+&ifc {
+ #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>;
+ status = "okay";
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@1,0 {
+ compatible = "fsl,ifc-nand";
+ reg = <0x1 0x0 0x10000>;
+ };
+
+ fpga: board-control@2,0 {
+ compatible = "fsl,ls1046aqds-fpga", "fsl,fpga-qixis";
+ reg = <0x2 0x0 0x0000100>;
+ };
+};
+
+&lpuart0 {
+ status = "okay";
+};
+
+&qspi {
+ num-cs = <2>;
+ bus-num = <0>;
+ status = "okay";
+
+ qflash0: s25fl128s@0 {
+ compatible = "spansion,m25p80";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
new file mode 100644
index 000000000000..d1ccc000d05a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -0,0 +1,150 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1046A family SoC.
+ *
+ * Copyright 2016, Freescale Semiconductor, Inc.
+ *
+ * Mingkai Hu <mingkai.hu@nxp.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-ls1046a.dtsi"
+
+/ {
+ model = "LS1046A RDB Board";
+ compatible = "fsl,ls1046a-rdb", "fsl,ls1046a";
+
+ aliases {
+ serial0 = &duart0;
+ serial1 = &duart1;
+ serial2 = &duart2;
+ serial3 = &duart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&duart0 {
+ status = "okay";
+};
+
+&duart1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ temp-sensor@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ eeprom@56 {
+ compatible = "atmel,24c512";
+ reg = <0x52>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c512";
+ reg = <0x53>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf2129";
+ reg = <0x51>;
+ };
+};
+
+&ifc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* NAND Flashe and CPLD on board */
+ ranges = <0x0 0x0 0x0 0x7e800000 0x00010000
+ 0x2 0x0 0x0 0x7fb00000 0x00000100>;
+ status = "okay";
+
+ nand@0,0 {
+ compatible = "fsl,ifc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x0 0x10000>;
+ };
+
+ cpld: board-control@2,0 {
+ compatible = "fsl,ls1046ardb-cpld";
+ reg = <0x2 0x0 0x0000100>;
+ };
+};
+
+&qspi {
+ num-cs = <2>;
+ bus-num = <0>;
+ status = "okay";
+
+ qflash0: s25fs512s@0 {
+ compatible = "spansion,m25p80";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+
+ qflash1: s25fs512s@1 {
+ compatible = "spansion,m25p80";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <20000000>;
+ reg = <1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
new file mode 100644
index 000000000000..38806ca53829
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -0,0 +1,515 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1046A family SoC.
+ *
+ * Copyright 2016, Freescale Semiconductor, Inc.
+ *
+ * Mingkai Hu <mingkai.hu@nxp.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.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "fsl,ls1046a";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ crypto = &crypto;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0>;
+ clocks = <&clockgen 1 0>;
+ next-level-cache = <&l2>;
+ cpu-idle-states = <&CPU_PH20>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x1>;
+ clocks = <&clockgen 1 0>;
+ next-level-cache = <&l2>;
+ cpu-idle-states = <&CPU_PH20>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x2>;
+ clocks = <&clockgen 1 0>;
+ next-level-cache = <&l2>;
+ cpu-idle-states = <&CPU_PH20>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x3>;
+ clocks = <&clockgen 1 0>;
+ next-level-cache = <&l2>;
+ cpu-idle-states = <&CPU_PH20>;
+ };
+
+ l2: l2-cache {
+ compatible = "cache";
+ };
+ };
+
+ idle-states {
+ /*
+ * PSCI node is not added default, U-boot will add missing
+ * parts if it determines to use PSCI.
+ */
+ entry-method = "arm,psci";
+
+ CPU_PH20: cpu-ph20 {
+ compatible = "arm,idle-state";
+ idle-state-name = "PH20";
+ arm,psci-suspend-param = <0x00010000>;
+ entry-latency-us = <1000>;
+ exit-latency-us = <1000>;
+ min-residency-us = <3000>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ };
+
+ 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 = <GIC_PPI 13 (GIC_CPU_MASK_RAW(0xf) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_RAW(0xf) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_RAW(0xf) |
+ IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_RAW(0xf) |
+ IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a72-pmu";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>,
+ <&cpu1>,
+ <&cpu2>,
+ <&cpu3>;
+ };
+
+ gic: interrupt-controller@1400000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x1410000 0 0x10000>, /* GICD */
+ <0x0 0x1420000 0 0x20000>, /* GICC */
+ <0x0 0x1440000 0 0x20000>, /* GICH */
+ <0x0 0x1460000 0 0x20000>; /* GICV */
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_RAW(0xf) |
+ IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ddr: memory-controller@1080000 {
+ compatible = "fsl,qoriq-memory-controller";
+ reg = <0x0 0x1080000 0x0 0x1000>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ big-endian;
+ };
+
+ ifc: ifc@1530000 {
+ compatible = "fsl,ifc", "simple-bus";
+ reg = <0x0 0x1530000 0x0 0x10000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ qspi: quadspi@1550000 {
+ compatible = "fsl,ls1021a-qspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x1550000 0x0 0x10000>,
+ <0x0 0x40000000 0x0 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "qspi_en", "qspi";
+ clocks = <&clockgen 4 1>, <&clockgen 4 1>;
+ big-endian;
+ fsl,qspi-has-second-chip;
+ status = "disabled";
+ };
+
+ esdhc: esdhc@1560000 {
+ compatible = "fsl,esdhc";
+ reg = <0x0 0x1560000 0x0 0x10000>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ voltage-ranges = <1800 1800 3300 3300>;
+ sdhci,auto-cmd12;
+ big-endian;
+ bus-width = <4>;
+ };
+
+ scfg: scfg@1570000 {
+ compatible = "fsl,ls1046a-scfg", "syscon";
+ reg = <0x0 0x1570000 0x0 0x10000>;
+ big-endian;
+ };
+
+ crypto: crypto@1700000 {
+ compatible = "fsl,sec-v5.4", "fsl,sec-v5.0",
+ "fsl,sec-v4.0";
+ fsl,sec-era = <8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x00 0x1700000 0x100000>;
+ reg = <0x00 0x1700000 0x0 0x100000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+
+ sec_jr0: jr@10000 {
+ compatible = "fsl,sec-v5.4-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x10000 0x10000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr@20000 {
+ compatible = "fsl,sec-v5.4-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x20000 0x10000>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr2: jr@30000 {
+ compatible = "fsl,sec-v5.4-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x30000 0x10000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr3: jr@40000 {
+ compatible = "fsl,sec-v5.4-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x40000 0x10000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ dcfg: dcfg@1ee0000 {
+ compatible = "fsl,ls1046a-dcfg", "syscon";
+ reg = <0x0 0x1ee0000 0x0 0x10000>;
+ big-endian;
+ };
+
+ clockgen: clocking@1ee1000 {
+ compatible = "fsl,ls1046a-clockgen";
+ reg = <0x0 0x1ee1000 0x0 0x1000>;
+ #clock-cells = <2>;
+ clocks = <&sysclk>;
+ };
+
+ dspi: dspi@2100000 {
+ compatible = "fsl,ls1021a-v1.0-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dspi";
+ clocks = <&clockgen 4 1>;
+ 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 = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ 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 = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@21a0000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x21a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@21b0000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x21b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ status = "disabled";
+ };
+
+ duart0: serial@21c0500 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x00 0x21c0500 0x0 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ };
+
+ duart1: serial@21c0600 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x00 0x21c0600 0x0 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ };
+
+ duart2: serial@21d0500 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21d0500 0x0 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ };
+
+ duart3: serial@21d0600 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21d0600 0x0 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ };
+
+ gpio0: gpio@2300000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2300000 0x0 0x10000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@2310000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2310000 0x0 0x10000>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2320000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2320000 0x0 0x10000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@2330000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2330000 0x0 0x10000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ lpuart0: serial@2950000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2950000 0x0 0x1000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart1: serial@2960000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2960000 0x0 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart2: serial@2970000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2970000 0x0 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart3: serial@2980000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2980000 0x0 0x1000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart4: serial@2990000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2990000 0x0 0x1000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart5: serial@29a0000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x29a0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ wdog0: watchdog@2ad0000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0x0 0x2ad0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ 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 = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma-tx", "edma-err";
+ dma-channels = <32>;
+ big-endian;
+ clock-names = "dmamux0", "dmamux1";
+ clocks = <&clockgen 4 1>,
+ <&clockgen 4 1>;
+ };
+
+ usb0: usb@2f00000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x2f00000 0x0 0x10000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ snps,quirk-frame-length-adjustment = <0x20>;
+ };
+
+ usb1: usb@3000000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3000000 0x0 0x10000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ snps,quirk-frame-length-adjustment = <0x20>;
+ };
+
+ usb2: usb@3100000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ snps,quirk-frame-length-adjustment = <0x20>;
+ };
+
+ sata: sata@3200000 {
+ compatible = "fsl,ls1046a-ahci";
+ reg = <0x0 0x3200000 0x0 0x10000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
index b0dd010979e7..8bc1f8f6fcfc 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
@@ -46,7 +46,7 @@
/dts-v1/;
-/include/ "fsl-ls2080a.dtsi"
+#include "fsl-ls2080a.dtsi"
/ {
model = "Freescale Layerscape 2080a QDS Board";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
index ad0ebb8a1949..265e0a8b107b 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
@@ -46,7 +46,7 @@
/dts-v1/;
-/include/ "fsl-ls2080a.dtsi"
+#include "fsl-ls2080a.dtsi"
/ {
model = "Freescale Layerscape 2080a RDB Board";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
index 505d038078a3..290604b0a603 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
@@ -46,7 +46,7 @@
/dts-v1/;
-/include/ "fsl-ls2080a.dtsi"
+#include "fsl-ls2080a.dtsi"
/ {
model = "Freescale Layerscape 2080a software Simulator model";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index d058e56db72d..e5935f28848c 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -44,6 +44,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <dt-bindings/thermal/thermal.h>
+
/ {
compatible = "fsl,ls2080a";
interrupt-parent = <&gic>;
@@ -62,15 +64,16 @@
*/
/* We have 4 clusters having 2 Cortex-A57 cores each */
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x0>;
clocks = <&clockgen 1 0>;
next-level-cache = <&cluster0_l2>;
+ #cooling-cells = <2>;
};
- cpu@1 {
+ cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x1>;
@@ -78,15 +81,16 @@
next-level-cache = <&cluster0_l2>;
};
- cpu@100 {
+ cpu2: cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x100>;
clocks = <&clockgen 1 1>;
next-level-cache = <&cluster1_l2>;
+ #cooling-cells = <2>;
};
- cpu@101 {
+ cpu3: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x101>;
@@ -94,15 +98,16 @@
next-level-cache = <&cluster1_l2>;
};
- cpu@200 {
+ cpu4: cpu@200 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x200>;
clocks = <&clockgen 1 2>;
next-level-cache = <&cluster2_l2>;
+ #cooling-cells = <2>;
};
- cpu@201 {
+ cpu5: cpu@201 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x201>;
@@ -110,15 +115,16 @@
next-level-cache = <&cluster2_l2>;
};
- cpu@300 {
+ cpu6: cpu@300 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x300>;
clocks = <&clockgen 1 3>;
next-level-cache = <&cluster3_l2>;
+ #cooling-cells = <2>;
};
- cpu@301 {
+ cpu7: cpu@301 {
device_type = "cpu";
compatible = "arm,cortex-a57";
reg = <0x301>;
@@ -222,6 +228,100 @@
little-endian;
};
+ tmu: tmu@1f80000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0x0 0x1f80000 0x0 0x10000>;
+ interrupts = <0 23 0x4>;
+ fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>;
+ fsl,tmu-calibration = <0x00000000 0x00000026
+ 0x00000001 0x0000002d
+ 0x00000002 0x00000032
+ 0x00000003 0x00000039
+ 0x00000004 0x0000003f
+ 0x00000005 0x00000046
+ 0x00000006 0x0000004d
+ 0x00000007 0x00000054
+ 0x00000008 0x0000005a
+ 0x00000009 0x00000061
+ 0x0000000a 0x0000006a
+ 0x0000000b 0x00000071
+
+ 0x00010000 0x00000025
+ 0x00010001 0x0000002c
+ 0x00010002 0x00000035
+ 0x00010003 0x0000003d
+ 0x00010004 0x00000045
+ 0x00010005 0x0000004e
+ 0x00010006 0x00000057
+ 0x00010007 0x00000061
+ 0x00010008 0x0000006b
+ 0x00010009 0x00000076
+
+ 0x00020000 0x00000029
+ 0x00020001 0x00000033
+ 0x00020002 0x0000003d
+ 0x00020003 0x00000049
+ 0x00020004 0x00000056
+ 0x00020005 0x00000061
+ 0x00020006 0x0000006d
+
+ 0x00030000 0x00000021
+ 0x00030001 0x0000002a
+ 0x00030002 0x0000003c
+ 0x00030003 0x0000004e>;
+ little-endian;
+ #thermal-sensor-cells = <1>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+
+ thermal-sensors = <&tmu 4>;
+
+ trips {
+ cpu_alert: cpu-alert {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit: cpu-crit {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map1 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu2 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map2 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu4 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map3 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu6 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
serial0: serial@21c0500 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x0 0x21c0500 0x0 0x100>;
diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
index d5f43a06b1c1..c8b8f803cf90 100644
--- a/arch/arm64/boot/dts/hisilicon/Makefile
+++ b/arch/arm64/boot/dts/hisilicon/Makefile
@@ -1,6 +1,7 @@
dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
dtb-$(CONFIG_ARCH_HISI) += hip05-d02.dtb
dtb-$(CONFIG_ARCH_HISI) += hip06-d03.dtb
+dtb-$(CONFIG_ARCH_HISI) += hip07-d05.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index e0ea60382087..470461ddd427 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -364,6 +364,7 @@
reg = <0x0 0xf7010000 0x0 0x27c>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
#gpio-range-cells = <3>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <7>;
@@ -402,6 +403,7 @@
reg = <0x0 0xf7010800 0x0 0x28c>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
};
@@ -410,6 +412,7 @@
reg = <0x0 0xf8001800 0x0 0x78>;
#address-cells = <1>;
#size-cells = <1>;
+ #pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
};
diff --git a/arch/arm64/boot/dts/hisilicon/hip06-d03.dts b/arch/arm64/boot/dts/hisilicon/hip06-d03.dts
index f54b28359607..7c4114a67753 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06-d03.dts
+++ b/arch/arm64/boot/dts/hisilicon/hip06-d03.dts
@@ -41,18 +41,10 @@
status = "ok";
};
-&sas0 {
- status = "ok";
-};
-
&sas1 {
status = "ok";
};
-&sas2 {
- status = "ok";
-};
-
&usb_ohci {
status = "ok";
};
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index b548763366dd..a049b64f2101 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -318,11 +318,17 @@
#size-cells = <2>;
ranges;
+ refclk: refclk {
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ #clock-cells = <0>;
+ };
+
usb_ohci: ohci@a7030000 {
compatible = "generic-ohci";
reg = <0x0 0xa7030000 0x0 0x10000>;
interrupt-parent = <&mbigen_usb>;
- interrupts = <64 4>;
+ interrupts = <640 4>;
dma-coherent;
status = "disabled";
};
@@ -331,7 +337,7 @@
compatible = "generic-ehci";
reg = <0x0 0xa7020000 0x0 0x10000>;
interrupt-parent = <&mbigen_usb>;
- interrupts = <65 4>;
+ interrupts = <641 4>;
dma-coherent;
status = "disabled";
};
@@ -508,7 +514,7 @@
};
};
- eth0: ethernet@4{
+ eth0: ethernet-4{
compatible = "hisilicon,hns-nic-v2";
ae-handle = <&dsaf0>;
port-idx-in-ae = <4>;
@@ -517,7 +523,7 @@
dma-coherent;
};
- eth1: ethernet@5{
+ eth1: ethernet-5{
compatible = "hisilicon,hns-nic-v2";
ae-handle = <&dsaf0>;
port-idx-in-ae = <5>;
@@ -526,7 +532,7 @@
dma-coherent;
};
- eth2: ethernet@0{
+ eth2: ethernet-0{
compatible = "hisilicon,hns-nic-v2";
ae-handle = <&dsaf0>;
port-idx-in-ae = <0>;
@@ -535,7 +541,7 @@
dma-coherent;
};
- eth3: ethernet@1{
+ eth3: ethernet-1{
compatible = "hisilicon,hns-nic-v2";
ae-handle = <&dsaf0>;
port-idx-in-ae = <1>;
@@ -552,6 +558,7 @@
ctrl-reset-reg = <0xa60>;
ctrl-reset-sts-reg = <0x5a30>;
ctrl-clock-ena-reg = <0x338>;
+ clocks = <&refclk 0>;
queue-count = <16>;
phy-count = <8>;
dma-coherent;
@@ -590,10 +597,11 @@
reg = <0 0xa2000000 0 0x10000>;
sas-addr = [50 01 88 20 16 00 00 00];
hisilicon,sas-syscon = <&pcie_subctl>;
- am-max-trans;
+ hip06-sas-v2-quirk-amt;
ctrl-reset-reg = <0xa18>;
ctrl-reset-sts-reg = <0x5a0c>;
ctrl-clock-ena-reg = <0x318>;
+ clocks = <&refclk 0>;
queue-count = <16>;
phy-count = <8>;
dma-coherent;
@@ -635,6 +643,7 @@
ctrl-reset-reg = <0xae0>;
ctrl-reset-sts-reg = <0x5a70>;
ctrl-clock-ena-reg = <0x3a8>;
+ clocks = <&refclk 0>;
queue-count = <16>;
phy-count = <9>;
dma-coherent;
diff --git a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts
new file mode 100644
index 000000000000..e05844230583
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts
@@ -0,0 +1,66 @@
+/**
+ * dts file for Hisilicon D05 Development Board
+ *
+ * Copyright (C) 2016 Hisilicon 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
+ * publishhed by the Free Software Foundation.
+ *
+ */
+
+/dts-v1/;
+
+#include "hip07.dtsi"
+
+/ {
+ model = "Hisilicon Hip07 D05 Development Board";
+ compatible = "hisilicon,hip07-d05";
+
+ /* the mem node will be updated by UEFI. */
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x00000000 0x0 0x40000000>;
+ numa-node-id = <0>;
+ };
+
+ distance-map {
+ compatible = "numa-distance-map-v1";
+ distance-matrix = <0 0 10>,
+ <0 1 15>,
+ <0 2 20>,
+ <0 3 25>,
+ <1 0 15>,
+ <1 1 10>,
+ <1 2 25>,
+ <1 3 30>,
+ <2 0 20>,
+ <2 1 25>,
+ <2 2 10>,
+ <2 3 15>,
+ <3 0 25>,
+ <3 1 30>,
+ <3 2 15>,
+ <3 3 10>;
+ };
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ status = "ok";
+};
+
+&usb_ohci {
+ status = "ok";
+};
+
+&usb_ehci {
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
new file mode 100644
index 000000000000..5144eb1c179d
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
@@ -0,0 +1,1059 @@
+/**
+ * dts file for Hisilicon D05 Development Board
+ *
+ * Copyright (C) 2016 Hisilicon 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
+ * publishhed by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "hisilicon,hip07-d05";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ core2 {
+ cpu = <&cpu2>;
+ };
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu4>;
+ };
+ core1 {
+ cpu = <&cpu5>;
+ };
+ core2 {
+ cpu = <&cpu6>;
+ };
+ core3 {
+ cpu = <&cpu7>;
+ };
+ };
+
+ cluster2 {
+ core0 {
+ cpu = <&cpu8>;
+ };
+ core1 {
+ cpu = <&cpu9>;
+ };
+ core2 {
+ cpu = <&cpu10>;
+ };
+ core3 {
+ cpu = <&cpu11>;
+ };
+ };
+
+ cluster3 {
+ core0 {
+ cpu = <&cpu12>;
+ };
+ core1 {
+ cpu = <&cpu13>;
+ };
+ core2 {
+ cpu = <&cpu14>;
+ };
+ core3 {
+ cpu = <&cpu15>;
+ };
+ };
+
+ cluster4 {
+ core0 {
+ cpu = <&cpu16>;
+ };
+ core1 {
+ cpu = <&cpu17>;
+ };
+ core2 {
+ cpu = <&cpu18>;
+ };
+ core3 {
+ cpu = <&cpu19>;
+ };
+ };
+
+ cluster5 {
+ core0 {
+ cpu = <&cpu20>;
+ };
+ core1 {
+ cpu = <&cpu21>;
+ };
+ core2 {
+ cpu = <&cpu22>;
+ };
+ core3 {
+ cpu = <&cpu23>;
+ };
+ };
+
+ cluster6 {
+ core0 {
+ cpu = <&cpu24>;
+ };
+ core1 {
+ cpu = <&cpu25>;
+ };
+ core2 {
+ cpu = <&cpu26>;
+ };
+ core3 {
+ cpu = <&cpu27>;
+ };
+ };
+
+ cluster7 {
+ core0 {
+ cpu = <&cpu28>;
+ };
+ core1 {
+ cpu = <&cpu29>;
+ };
+ core2 {
+ cpu = <&cpu30>;
+ };
+ core3 {
+ cpu = <&cpu31>;
+ };
+ };
+
+ cluster8 {
+ core0 {
+ cpu = <&cpu32>;
+ };
+ core1 {
+ cpu = <&cpu33>;
+ };
+ core2 {
+ cpu = <&cpu34>;
+ };
+ core3 {
+ cpu = <&cpu35>;
+ };
+ };
+
+ cluster9 {
+ core0 {
+ cpu = <&cpu36>;
+ };
+ core1 {
+ cpu = <&cpu37>;
+ };
+ core2 {
+ cpu = <&cpu38>;
+ };
+ core3 {
+ cpu = <&cpu39>;
+ };
+ };
+
+ cluster10 {
+ core0 {
+ cpu = <&cpu40>;
+ };
+ core1 {
+ cpu = <&cpu41>;
+ };
+ core2 {
+ cpu = <&cpu42>;
+ };
+ core3 {
+ cpu = <&cpu43>;
+ };
+ };
+
+ cluster11 {
+ core0 {
+ cpu = <&cpu44>;
+ };
+ core1 {
+ cpu = <&cpu45>;
+ };
+ core2 {
+ cpu = <&cpu46>;
+ };
+ core3 {
+ cpu = <&cpu47>;
+ };
+ };
+
+ cluster12 {
+ core0 {
+ cpu = <&cpu48>;
+ };
+ core1 {
+ cpu = <&cpu49>;
+ };
+ core2 {
+ cpu = <&cpu50>;
+ };
+ core3 {
+ cpu = <&cpu51>;
+ };
+ };
+
+ cluster13 {
+ core0 {
+ cpu = <&cpu52>;
+ };
+ core1 {
+ cpu = <&cpu53>;
+ };
+ core2 {
+ cpu = <&cpu54>;
+ };
+ core3 {
+ cpu = <&cpu55>;
+ };
+ };
+
+ cluster14 {
+ core0 {
+ cpu = <&cpu56>;
+ };
+ core1 {
+ cpu = <&cpu57>;
+ };
+ core2 {
+ cpu = <&cpu58>;
+ };
+ core3 {
+ cpu = <&cpu59>;
+ };
+ };
+
+ cluster15 {
+ core0 {
+ cpu = <&cpu60>;
+ };
+ core1 {
+ cpu = <&cpu61>;
+ };
+ core2 {
+ cpu = <&cpu62>;
+ };
+ core3 {
+ cpu = <&cpu63>;
+ };
+ };
+ };
+
+ cpu0: cpu@10000 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10000>;
+ enable-method = "psci";
+ next-level-cache = <&cluster0_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu1: cpu@10001 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10001>;
+ enable-method = "psci";
+ next-level-cache = <&cluster0_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu2: cpu@10002 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10002>;
+ enable-method = "psci";
+ next-level-cache = <&cluster0_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu3: cpu@10003 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10003>;
+ enable-method = "psci";
+ next-level-cache = <&cluster0_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu4: cpu@10100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10100>;
+ enable-method = "psci";
+ next-level-cache = <&cluster1_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu5: cpu@10101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10101>;
+ enable-method = "psci";
+ next-level-cache = <&cluster1_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu6: cpu@10102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10102>;
+ enable-method = "psci";
+ next-level-cache = <&cluster1_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu7: cpu@10103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10103>;
+ enable-method = "psci";
+ next-level-cache = <&cluster1_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu8: cpu@10200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10200>;
+ enable-method = "psci";
+ next-level-cache = <&cluster2_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu9: cpu@10201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10201>;
+ enable-method = "psci";
+ next-level-cache = <&cluster2_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu10: cpu@10202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10202>;
+ enable-method = "psci";
+ next-level-cache = <&cluster2_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu11: cpu@10203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10203>;
+ enable-method = "psci";
+ next-level-cache = <&cluster2_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu12: cpu@10300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10300>;
+ enable-method = "psci";
+ next-level-cache = <&cluster3_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu13: cpu@10301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10301>;
+ enable-method = "psci";
+ next-level-cache = <&cluster3_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu14: cpu@10302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10302>;
+ enable-method = "psci";
+ next-level-cache = <&cluster3_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu15: cpu@10303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x10303>;
+ enable-method = "psci";
+ next-level-cache = <&cluster3_l2>;
+ numa-node-id = <0>;
+ };
+
+ cpu16: cpu@30000 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30000>;
+ enable-method = "psci";
+ next-level-cache = <&cluster4_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu17: cpu@30001 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30001>;
+ enable-method = "psci";
+ next-level-cache = <&cluster4_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu18: cpu@30002 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30002>;
+ enable-method = "psci";
+ next-level-cache = <&cluster4_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu19: cpu@30003 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30003>;
+ enable-method = "psci";
+ next-level-cache = <&cluster4_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu20: cpu@30100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30100>;
+ enable-method = "psci";
+ next-level-cache = <&cluster5_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu21: cpu@30101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30101>;
+ enable-method = "psci";
+ next-level-cache = <&cluster5_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu22: cpu@30102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30102>;
+ enable-method = "psci";
+ next-level-cache = <&cluster5_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu23: cpu@30103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30103>;
+ enable-method = "psci";
+ next-level-cache = <&cluster5_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu24: cpu@30200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30200>;
+ enable-method = "psci";
+ next-level-cache = <&cluster6_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu25: cpu@30201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30201>;
+ enable-method = "psci";
+ next-level-cache = <&cluster6_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu26: cpu@30202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30202>;
+ enable-method = "psci";
+ next-level-cache = <&cluster6_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu27: cpu@30203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30203>;
+ enable-method = "psci";
+ next-level-cache = <&cluster6_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu28: cpu@30300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30300>;
+ enable-method = "psci";
+ next-level-cache = <&cluster7_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu29: cpu@30301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30301>;
+ enable-method = "psci";
+ next-level-cache = <&cluster7_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu30: cpu@30302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30302>;
+ enable-method = "psci";
+ next-level-cache = <&cluster7_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu31: cpu@30303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x30303>;
+ enable-method = "psci";
+ next-level-cache = <&cluster7_l2>;
+ numa-node-id = <1>;
+ };
+
+ cpu32: cpu@50000 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50000>;
+ enable-method = "psci";
+ next-level-cache = <&cluster8_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu33: cpu@50001 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50001>;
+ enable-method = "psci";
+ next-level-cache = <&cluster8_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu34: cpu@50002 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50002>;
+ enable-method = "psci";
+ next-level-cache = <&cluster8_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu35: cpu@50003 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50003>;
+ enable-method = "psci";
+ next-level-cache = <&cluster8_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu36: cpu@50100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50100>;
+ enable-method = "psci";
+ next-level-cache = <&cluster9_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu37: cpu@50101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50101>;
+ enable-method = "psci";
+ next-level-cache = <&cluster9_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu38: cpu@50102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50102>;
+ enable-method = "psci";
+ next-level-cache = <&cluster9_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu39: cpu@50103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50103>;
+ enable-method = "psci";
+ next-level-cache = <&cluster9_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu40: cpu@50200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50200>;
+ enable-method = "psci";
+ next-level-cache = <&cluster10_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu41: cpu@50201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50201>;
+ enable-method = "psci";
+ next-level-cache = <&cluster10_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu42: cpu@50202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50202>;
+ enable-method = "psci";
+ next-level-cache = <&cluster10_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu43: cpu@50203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50203>;
+ enable-method = "psci";
+ next-level-cache = <&cluster10_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu44: cpu@50300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50300>;
+ enable-method = "psci";
+ next-level-cache = <&cluster11_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu45: cpu@50301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50301>;
+ enable-method = "psci";
+ next-level-cache = <&cluster11_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu46: cpu@50302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50302>;
+ enable-method = "psci";
+ next-level-cache = <&cluster11_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu47: cpu@50303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x50303>;
+ enable-method = "psci";
+ next-level-cache = <&cluster11_l2>;
+ numa-node-id = <2>;
+ };
+
+ cpu48: cpu@70000 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70000>;
+ enable-method = "psci";
+ next-level-cache = <&cluster12_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu49: cpu@70001 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70001>;
+ enable-method = "psci";
+ next-level-cache = <&cluster12_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu50: cpu@70002 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70002>;
+ enable-method = "psci";
+ next-level-cache = <&cluster12_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu51: cpu@70003 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70003>;
+ enable-method = "psci";
+ next-level-cache = <&cluster12_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu52: cpu@70100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70100>;
+ enable-method = "psci";
+ next-level-cache = <&cluster13_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu53: cpu@70101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70101>;
+ enable-method = "psci";
+ next-level-cache = <&cluster13_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu54: cpu@70102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70102>;
+ enable-method = "psci";
+ next-level-cache = <&cluster13_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu55: cpu@70103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70103>;
+ enable-method = "psci";
+ next-level-cache = <&cluster13_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu56: cpu@70200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70200>;
+ enable-method = "psci";
+ next-level-cache = <&cluster14_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu57: cpu@70201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70201>;
+ enable-method = "psci";
+ next-level-cache = <&cluster14_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu58: cpu@70202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70202>;
+ enable-method = "psci";
+ next-level-cache = <&cluster14_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu59: cpu@70203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70203>;
+ enable-method = "psci";
+ next-level-cache = <&cluster14_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu60: cpu@70300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70300>;
+ enable-method = "psci";
+ next-level-cache = <&cluster15_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu61: cpu@70301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70301>;
+ enable-method = "psci";
+ next-level-cache = <&cluster15_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu62: cpu@70302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70302>;
+ enable-method = "psci";
+ next-level-cache = <&cluster15_l2>;
+ numa-node-id = <3>;
+ };
+
+ cpu63: cpu@70303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x70303>;
+ enable-method = "psci";
+ next-level-cache = <&cluster15_l2>;
+ numa-node-id = <3>;
+ };
+
+ cluster0_l2: l2-cache0 {
+ compatible = "cache";
+ };
+
+ cluster1_l2: l2-cache1 {
+ compatible = "cache";
+ };
+
+ cluster2_l2: l2-cache2 {
+ compatible = "cache";
+ };
+
+ cluster3_l2: l2-cache3 {
+ compatible = "cache";
+ };
+
+ cluster4_l2: l2-cache4 {
+ compatible = "cache";
+ };
+
+ cluster5_l2: l2-cache5 {
+ compatible = "cache";
+ };
+
+ cluster6_l2: l2-cache6 {
+ compatible = "cache";
+ };
+
+ cluster7_l2: l2-cache7 {
+ compatible = "cache";
+ };
+
+ cluster8_l2: l2-cache8 {
+ compatible = "cache";
+ };
+
+ cluster9_l2: l2-cache9 {
+ compatible = "cache";
+ };
+
+ cluster10_l2: l2-cache10 {
+ compatible = "cache";
+ };
+
+ cluster11_l2: l2-cache11 {
+ compatible = "cache";
+ };
+
+ cluster12_l2: l2-cache12 {
+ compatible = "cache";
+ };
+
+ cluster13_l2: l2-cache13 {
+ compatible = "cache";
+ };
+
+ cluster14_l2: l2-cache14 {
+ compatible = "cache";
+ };
+
+ cluster15_l2: l2-cache15 {
+ compatible = "cache";
+ };
+ };
+
+ gic: interrupt-controller@4d000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+ #redistributor-regions = <4>;
+ redistributor-stride = <0x0 0x40000>;
+ reg = <0x0 0x4d000000 0x0 0x10000>, /* GICD */
+ <0x0 0x4d100000 0x0 0x400000>, /* p0 GICR node 0 */
+ <0x0 0x6d100000 0x0 0x400000>, /* p0 GICR node 1 */
+ <0x400 0x4d100000 0x0 0x400000>, /* p1 GICR node 2 */
+ <0x400 0x6d100000 0x0 0x400000>, /* p1 GICR node 3 */
+ <0x0 0xfe000000 0x0 0x10000>, /* GICC */
+ <0x0 0xfe010000 0x0 0x10000>, /* GICH */
+ <0x0 0xfe020000 0x0 0x10000>; /* GICV */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+ p0_its_peri_a: interrupt-controller@4c000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x0 0x4c000000 0x0 0x40000>;
+ };
+
+ p0_its_peri_b: interrupt-controller@6c000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x0 0x6c000000 0x0 0x40000>;
+ };
+
+ p0_its_dsa_a: interrupt-controller@c6000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x0 0xc6000000 0x0 0x40000>;
+ };
+
+ p0_its_dsa_b: interrupt-controller@8,c6000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x8 0xc6000000 0x0 0x40000>;
+ };
+
+ p1_its_peri_a: interrupt-controller@400,4c000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x400 0x4c000000 0x0 0x40000>;
+ };
+
+ p1_its_peri_b: interrupt-controller@400,6c000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x400 0x6c000000 0x0 0x40000>;
+ };
+
+ p1_its_dsa_a: interrupt-controller@400,c6000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x400 0xc6000000 0x0 0x40000>;
+ };
+
+ p1_its_dsa_b: interrupt-controller@408,c6000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x408 0xc6000000 0x0 0x40000>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a72-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ p0_mbigen_peri_b: interrupt-controller@60080000 {
+ compatible = "hisilicon,mbigen-v2";
+ reg = <0x0 0x60080000 0x0 0x10000>;
+
+ mbigen_uart: uart_intc {
+ msi-parent = <&p0_its_peri_b 0x120c7>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ num-pins = <1>;
+ };
+ };
+
+ p0_mbigen_pcie_a: interrupt-controller@a0080000 {
+ compatible = "hisilicon,mbigen-v2";
+ reg = <0x0 0xa0080000 0x0 0x10000>;
+
+ mbigen_usb: intc_usb {
+ msi-parent = <&p0_its_dsa_a 0x40080>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ num-pins = <2>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ uart0: uart@602b0000 {
+ compatible = "arm,sbsa-uart";
+ reg = <0x0 0x602b0000 0x0 0x1000>;
+ interrupt-parent = <&mbigen_uart>;
+ interrupts = <807 4>;
+ current-speed = <115200>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ usb_ohci: ohci@a7030000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xa7030000 0x0 0x10000>;
+ interrupt-parent = <&mbigen_usb>;
+ interrupts = <640 4>;
+ dma-coherent;
+ status = "disabled";
+ };
+
+ usb_ehci: ehci@a7020000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xa7020000 0x0 0x10000>;
+ interrupt-parent = <&mbigen_usb>;
+ interrupts = <641 4>;
+ dma-coherent;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile
index cf3953124cef..1690883b931a 100644
--- a/arch/arm64/boot/dts/marvell/Makefile
+++ b/arch/arm64/boot/dts/marvell/Makefile
@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb
# Mvebu SoC Family
dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb
dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb
dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index a59d36cd6caf..89de0a751093 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -56,7 +56,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
};
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
new file mode 100644
index 000000000000..83178d909fc2
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
@@ -0,0 +1,82 @@
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board
+ * Copyright (C) 2016 Marvell
+ *
+ * Romain Perier <romain.perier@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 , 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-372x.dtsi"
+
+/ {
+ model = "Globalscale Marvell ESPRESSOBin Board";
+ compatible = "globalscale,espressobin", "marvell,armada3720", "marvell,armada3710";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
+ };
+};
+
+/* J9 */
+&pcie0 {
+ status = "okay";
+};
+
+/* J6 */
+&sata {
+ status = "okay";
+};
+
+/* Exported on the micro USB connector J5 through an FTDI */
+&uart0 {
+ status = "okay";
+};
+
+/* J7 */
+&usb3 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 3b8eb45bdc76..bab5c6ff5745 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -91,7 +91,7 @@
#size-cells = <2>;
ranges;
- internal-regs {
+ internal-regs@d0000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 7b6136182ad0..a749ba2edec4 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -71,7 +71,7 @@
interrupt-parent = <&gic>;
ranges;
- config-space {
+ config-space@f0000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index 93ec8fef82a1..05222f749a45 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -52,7 +52,7 @@
interrupt-parent = <&gic>;
ranges;
- config-space {
+ config-space@f2000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index ee8db0556791..638820ce977d 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -52,7 +52,7 @@
interrupt-parent = <&gic>;
ranges;
- config-space {
+ config-space@f4000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
diff --git a/arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts b/arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
index 0d70d39fa8d2..fae6c6924705 100644
--- a/arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
+++ b/arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
@@ -54,7 +54,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@1000000 {
device_type = "memory";
/* the first 16MB is for firmwares' usage */
reg = <0 0x01000000 0 0x7f000000>;
diff --git a/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts b/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts
index 348c37ecf069..d47edad13e68 100644
--- a/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts
+++ b/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts
@@ -54,7 +54,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@1000000 {
device_type = "memory";
/* the first 16MB is for firmwares' usage */
reg = <0 0x01000000 0 0x7f000000>;
diff --git a/arch/arm64/boot/dts/marvell/berlin4ct.dtsi b/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
index 85c23facb9fe..d6b800fd26d0 100644
--- a/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
+++ b/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
@@ -142,7 +142,7 @@
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
- soc {
+ soc@f7000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index c2d588ca59b7..9c9fccbabb31 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -450,6 +450,9 @@
auxadc: auxadc@11001000 {
compatible = "mediatek,mt8173-auxadc";
reg = <0 0x11001000 0 0x1000>;
+ clocks = <&pericfg CLK_PERI_AUXADC>;
+ clock-names = "main";
+ #io-channel-cells = <1>;
};
uart0: serial@11002000 {
diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index 0f7cdf3e05c1..18941458cb4d 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -3,6 +3,7 @@ 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
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb
+dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb
always := $(dtb-y)
clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
new file mode 100644
index 000000000000..0d3c0996d832
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p3310.dtsi"
+
+/ {
+ model = "NVIDIA Tegra186 P2771-0000 Development Board";
+ compatible = "nvidia,p2771-0000", "nvidia,tegra186";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
new file mode 100644
index 000000000000..1abe2eceb3d1
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
@@ -0,0 +1,64 @@
+#include "tegra186.dtsi"
+
+/ {
+ model = "NVIDIA Tegra186 P3310 Processor Module";
+ compatible = "nvidia,p3310", "nvidia,tegra186";
+
+ aliases {
+ serial0 = &uarta;
+ };
+
+ chosen {
+ bootargs = "earlycon console=ttyS0,115200n8";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x2 0x00000000>;
+ };
+
+ serial@3100000 {
+ status = "okay";
+ };
+
+ hsp@3c00000 {
+ status = "okay";
+ };
+
+ cpus {
+ cpu@0 {
+ enable-method = "psci";
+ };
+
+ cpu@1 {
+ enable-method = "psci";
+ };
+
+ cpu@2 {
+ enable-method = "psci";
+ };
+
+ cpu@3 {
+ enable-method = "psci";
+ };
+
+ cpu@4 {
+ enable-method = "psci";
+ };
+
+ cpu@5 {
+ enable-method = "psci";
+ };
+ };
+
+ bpmp {
+ status = "okay";
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ status = "okay";
+ method = "smc";
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
new file mode 100644
index 000000000000..a918e10240fd
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -0,0 +1,398 @@
+#include <dt-bindings/gpio/tegra186-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "nvidia,tegra186";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ gpio: gpio@2200000 {
+ compatible = "nvidia,tegra186-gpio";
+ reg-names = "security", "gpio";
+ reg = <0x0 0x2200000 0x0 0x10000>,
+ <0x0 0x2210000 0x0 0x10000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ uarta: serial@3100000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x03100000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 55>;
+ clock-names = "serial";
+ resets = <&bpmp 47>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartb: serial@3110000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x03110000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 56>;
+ clock-names = "serial";
+ resets = <&bpmp 48>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartd: serial@3130000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x03130000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 77>;
+ clock-names = "serial";
+ resets = <&bpmp 50>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uarte: serial@3140000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x03140000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 194>;
+ clock-names = "serial";
+ resets = <&bpmp 132>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartf: serial@3150000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x03150000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 195>;
+ clock-names = "serial";
+ resets = <&bpmp 111>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ gen1_i2c: i2c@3160000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x03160000 0x0 0x10000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 47>;
+ clock-names = "div-clk";
+ resets = <&bpmp 19>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ cam_i2c: i2c@3180000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x03180000 0x0 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 75>;
+ clock-names = "div-clk";
+ resets = <&bpmp 21>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ /* shares pads with dpaux1 */
+ dp_aux_ch1_i2c: i2c@3190000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x03190000 0x0 0x10000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 86>;
+ clock-names = "div-clk";
+ resets = <&bpmp 22>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ /* controlled by BPMP, should not be enabled */
+ pwr_i2c: i2c@31a0000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x031a0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 48>;
+ clock-names = "div-clk";
+ resets = <&bpmp 23>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ /* shares pads with dpaux0 */
+ dp_aux_ch0_i2c: i2c@31b0000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x031b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 125>;
+ clock-names = "div-clk";
+ resets = <&bpmp 24>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ gen7_i2c: i2c@31c0000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x031c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 182>;
+ clock-names = "div-clk";
+ resets = <&bpmp 81>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ gen9_i2c: i2c@31e0000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x031e0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 183>;
+ clock-names = "div-clk";
+ resets = <&bpmp 83>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ sdmmc1: sdhci@3400000 {
+ compatible = "nvidia,tegra186-sdhci";
+ reg = <0x0 0x03400000 0x0 0x10000>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 52>;
+ clock-names = "sdhci";
+ resets = <&bpmp 33>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdmmc2: sdhci@3420000 {
+ compatible = "nvidia,tegra186-sdhci";
+ reg = <0x0 0x03420000 0x0 0x10000>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 53>;
+ clock-names = "sdhci";
+ resets = <&bpmp 34>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdmmc3: sdhci@3440000 {
+ compatible = "nvidia,tegra186-sdhci";
+ reg = <0x0 0x03440000 0x0 0x10000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 76>;
+ clock-names = "sdhci";
+ resets = <&bpmp 35>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdmmc4: sdhci@3460000 {
+ compatible = "nvidia,tegra186-sdhci";
+ reg = <0x0 0x03460000 0x0 0x10000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 54>;
+ clock-names = "sdhci";
+ resets = <&bpmp 36>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@3881000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x03881000 0x0 0x1000>,
+ <0x0 0x03882000 0x0 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ hsp_top0: hsp@3c00000 {
+ compatible = "nvidia,tegra186-hsp";
+ reg = <0x0 0x03c00000 0x0 0xa0000>;
+ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "doorbell";
+ #mbox-cells = <2>;
+ status = "disabled";
+ };
+
+ gen2_i2c: i2c@c240000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x0c240000 0x0 0x10000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 218>;
+ clock-names = "div-clk";
+ resets = <&bpmp 20>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ gen8_i2c: i2c@c250000 {
+ compatible = "nvidia,tegra186-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x0c250000 0x0 0x10000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&bpmp 219>;
+ clock-names = "div-clk";
+ resets = <&bpmp 82>;
+ reset-names = "i2c";
+ status = "disabled";
+ };
+
+ uartc: serial@c280000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x0c280000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 215>;
+ clock-names = "serial";
+ resets = <&bpmp 49>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartg: serial@c290000 {
+ compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x0c290000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp 216>;
+ clock-names = "serial";
+ resets = <&bpmp 112>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ gpio_aon: gpio@c2f0000 {
+ compatible = "nvidia,tegra186-gpio-aon";
+ reg-names = "security", "gpio";
+ reg = <0x0 0xc2f0000 0x0 0x1000>,
+ <0x0 0xc2f1000 0x0 0x1000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sysram@30000000 {
+ compatible = "nvidia,tegra186-sysram", "mmio-sram";
+ reg = <0x0 0x30000000 0x0 0x50000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0 0x0 0x0 0x30000000 0x0 0x50000>;
+
+ cpu_bpmp_tx: shmem@4e000 {
+ compatible = "nvidia,tegra186-bpmp-shmem";
+ reg = <0x0 0x4e000 0x0 0x1000>;
+ label = "cpu-bpmp-tx";
+ pool;
+ };
+
+ cpu_bpmp_rx: shmem@4f000 {
+ compatible = "nvidia,tegra186-bpmp-shmem";
+ reg = <0x0 0x4f000 0x0 0x1000>;
+ label = "cpu-bpmp-rx";
+ pool;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "nvidia,tegra186-denver", "arm,armv8";
+ device_type = "cpu";
+ reg = <0x000>;
+ };
+
+ cpu@1 {
+ compatible = "nvidia,tegra186-denver", "arm,armv8";
+ device_type = "cpu";
+ reg = <0x001>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a57", "arm,armv8";
+ device_type = "cpu";
+ reg = <0x100>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a57", "arm,armv8";
+ device_type = "cpu";
+ reg = <0x101>;
+ };
+
+ cpu@4 {
+ compatible = "arm,cortex-a57", "arm,armv8";
+ device_type = "cpu";
+ reg = <0x102>;
+ };
+
+ cpu@5 {
+ compatible = "arm,cortex-a57", "arm,armv8";
+ device_type = "cpu";
+ reg = <0x103>;
+ };
+ };
+
+ bpmp: bpmp {
+ compatible = "nvidia,tegra186-bpmp";
+ mboxes = <&hsp_top0 0 19>;
+ shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ bpmp_i2c: i2c {
+ compatible = "nvidia,tegra186-bpmp-i2c";
+ nvidia,bpmp-bus-id = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ 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>;
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
index 5fda583351d7..906fb836d241 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
@@ -21,6 +21,10 @@
reg = <0x0 0x80000000 0x1 0x0>;
};
+ gpu@57000000 {
+ vdd-supply = <&vdd_gpu>;
+ };
+
/* debug port */
serial@70006000 {
status = "okay";
@@ -291,4 +295,18 @@
clock-frequency = <32768>;
};
};
+
+ regulators {
+ vdd_gpu: regulator@100 {
+ compatible = "pwm-regulator";
+ reg = <100>;
+ pwms = <&pwm 1 4880>;
+ regulator-name = "VDD_GPU";
+ regulator-min-microvolt = <710000>;
+ regulator-max-microvolt = <1320000>;
+ enable-gpios = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ regulator-ramp-delay = <80>;
+ regulator-enable-ramp-delay = <1000>;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
index 983775e637a4..4c1ea7a08d43 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
@@ -7,6 +7,32 @@
model = "NVIDIA Jetson TX1 Developer Kit";
compatible = "nvidia,p2371-2180", "nvidia,tegra210";
+ pcie-controller@01003000 {
+ status = "okay";
+
+ avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
+ hvddio-pex-supply = <&vdd_1v8>;
+ dvddio-pex-supply = <&vdd_pex_1v05>;
+ dvdd-pex-pll-supply = <&vdd_pex_1v05>;
+ hvdd-pex-pll-e-supply = <&vdd_1v8>;
+ vddio-pex-ctl-supply = <&vdd_1v8>;
+
+ pci@1,0 {
+ phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>;
+ phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
+ status = "okay";
+ };
+
+ pci@2,0 {
+ phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
+ phy-names = "pcie-0";
+ status = "okay";
+ };
+ };
+
host1x@50000000 {
dsi@54300000 {
status = "okay";
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index c2becb603e11..7703227f5d1a 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -11,7 +11,8 @@
compatible = "google,smaug-rev8", "google,smaug-rev7",
"google,smaug-rev6", "google,smaug-rev5",
"google,smaug-rev4", "google,smaug-rev3",
- "google,smaug-rev1", "google,smaug", "nvidia,tegra210";
+ "google,smaug-rev2", "google,smaug-rev1",
+ "google,smaug", "nvidia,tegra210";
aliases {
serial0 = &uarta;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 46045fe719da..2f832df29da8 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -11,6 +11,69 @@
#address-cells = <2>;
#size-cells = <2>;
+ pcie-controller@01003000 {
+ compatible = "nvidia,tegra210-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 TEGRA210_CLK_PCIE>,
+ <&tegra_car TEGRA210_CLK_AFI>,
+ <&tegra_car TEGRA210_CLK_PLL_E>,
+ <&tegra_car TEGRA210_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";
+
+ 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 = <4>;
+ };
+
+ 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@50000000 {
compatible = "nvidia,tegra210-host1x", "simple-bus";
reg = <0x0 0x50000000 0x0 0x00034000>;
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 5dd05de5619b..cc0f02d9dd02 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -1,6 +1,9 @@
-dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb msm8916-mtp.dtb
-dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index bb062b547110..08bd5ebafb4e 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -15,6 +15,7 @@
#include "pm8916.dtsi"
#include "apq8016-sbc-soc-pins.dtsi"
#include "apq8016-sbc-pmic-pins.dtsi"
+#include <dt-bindings/sound/apq8016-lpass.h>
/ {
aliases {
@@ -251,6 +252,60 @@
vddio-supply = <&pm8916_l6>;
};
};
+
+ lpass_codec: codec{
+ status = "okay";
+ };
+
+ /*
+ Internal Codec
+ playback - Primary MI2S
+ capture - Ter MI2S
+
+ External Primary:
+ playback - secondary MI2S
+ capture - Quat MI2S
+
+ External Secondary:
+ playback - Quat MI2S
+ capture - Quat MI2S
+
+ */
+
+ sound: sound {
+ compatible = "qcom,apq8016-sbc-sndcard";
+ reg = <0x07702000 0x4>, <0x07702004 0x4>;
+ reg-names = "mic-iomux", "spkr-iomux";
+
+ status = "okay";
+ pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>;
+ pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>;
+ pinctrl-names = "default", "sleep";
+ qcom,model = "DB410c";
+ qcom,audio-routing =
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+
+ internal-codec-playback-dai-link@0 { /* I2S - Internal codec */
+ link-name = "WCD";
+ cpu { /* PRIMARY */
+ sound-dai = <&lpass MI2S_PRIMARY>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 0>, <&wcd_codec 0>;
+ };
+ };
+
+ internal-codec-capture-dai-link@0 { /* I2S - Internal codec */
+ link-name = "WCD-Capture";
+ cpu { /* PRIMARY */
+ sound-dai = <&lpass MI2S_TERTIARY>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 1>, <&wcd_codec 1>;
+ };
+ };
+ };
};
usb2513 {
@@ -278,6 +333,12 @@
};
};
+&wcd_codec {
+ status = "okay";
+ clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
+ clock-names = "mclk";
+};
+
&smd_rpm_regulators {
vdd_l1_l2_l3-supply = <&pm8916_s3>;
vdd_l5-supply = <&pm8916_s3>;
@@ -308,8 +369,8 @@
};
l2 {
- regulator-min-microvolt = <375000>;
- regulator-max-microvolt = <1525000>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
};
l3 {
@@ -328,8 +389,8 @@
};
l6 {
- regulator-min-microvolt = <1750000>;
- regulator-max-microvolt = <3337000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
};
l7 {
@@ -388,8 +449,8 @@
};
l17 {
- regulator-min-microvolt = <1750000>;
- regulator-max-microvolt = <3337000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
};
l18 {
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi
new file mode 100644
index 000000000000..0de95171d6d0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi
@@ -0,0 +1,15 @@
+
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+&pm8994_gpios {
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ls_exp_gpio_f>;
+
+ ls_exp_gpio_f: pm8916_mpp4 {
+ pinconf {
+ pins = "gpio5";
+ output-low;
+ power-source = <2>; // PM8994_GPIO_S4, 1.8V
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
index afb218cffc60..422959b87d12 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
@@ -12,7 +12,9 @@
*/
#include "msm8996.dtsi"
+#include "pm8994.dtsi"
#include "apq8096-db820c-pins.dtsi"
+#include "apq8096-db820c-pmic-pins.dtsi"
/ {
aliases {
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 466ca5705c99..f8ff327667c5 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -77,7 +77,7 @@
no-map;
};
- mpss@86800000 {
+ mpss_mem: mpss@86800000 {
reg = <0x0 0x86800000 0x0 0x2b00000>;
no-map;
};
@@ -504,6 +504,15 @@
reg-names = "lpass-lpaif";
};
+ lpass_codec: codec{
+ compatible = "qcom,msm8916-wcd-digital-codec";
+ reg = <0x0771c000 0x400>;
+ clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>,
+ <&gcc GCC_CODEC_DIGCODEC_CLK>;
+ clock-names = "ahbix-clk", "mclk";
+ #sound-dai-cells = <1>;
+ };
+
sdhc_1: sdhci@07824000 {
compatible = "qcom,sdhci-msm-v4";
reg = <0x07824900 0x11c>, <0x07824000 0x800>;
@@ -512,8 +521,10 @@
interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
clocks = <&gcc GCC_SDCC1_APPS_CLK>,
- <&gcc GCC_SDCC1_AHB_CLK>;
- clock-names = "core", "iface";
+ <&gcc GCC_SDCC1_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
+ mmc-ddr-1_8v;
bus-width = <8>;
non-removable;
status = "disabled";
@@ -527,8 +538,9 @@
interrupts = <0 125 0>, <0 221 0>;
interrupt-names = "hc_irq", "pwr_irq";
clocks = <&gcc GCC_SDCC2_APPS_CLK>,
- <&gcc GCC_SDCC2_AHB_CLK>;
- clock-names = "core", "iface";
+ <&gcc GCC_SDCC2_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
bus-width = <4>;
status = "disabled";
};
@@ -801,6 +813,49 @@
clock-names = "iface_clk";
};
};
+
+
+ hexagon@4080000 {
+ compatible = "qcom,q6v5-pil";
+ reg = <0x04080000 0x100>,
+ <0x04020000 0x040>;
+
+ reg-names = "qdsp6", "rmb";
+
+ interrupts-extended = <&intc 0 24 1>,
+ <&hexagon_smp2p_in 0 0>,
+ <&hexagon_smp2p_in 1 0>,
+ <&hexagon_smp2p_in 2 0>,
+ <&hexagon_smp2p_in 3 0>;
+ interrupt-names = "wdog", "fatal", "ready",
+ "handover", "stop-ack";
+
+ clocks = <&gcc GCC_MSS_CFG_AHB_CLK>,
+ <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>,
+ <&gcc GCC_BOOT_ROM_AHB_CLK>;
+ clock-names = "iface", "bus", "mem";
+
+ qcom,smem-states = <&hexagon_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
+ resets = <&scm 0>;
+ reset-names = "mss_restart";
+
+ mx-supply = <&pm8916_l3>;
+ pll-supply = <&pm8916_l7>;
+
+ qcom,halt-regs = <&tcsr 0x18000 0x19000 0x1a000>;
+
+ status = "disabled";
+
+ mba {
+ memory-region = <&mba_mem>;
+ };
+
+ mpss {
+ memory-region = <&mpss_mem>;
+ };
+ };
};
smd {
@@ -848,6 +903,14 @@
};
};
};
+
+ hexagon {
+ interrupts = <0 25 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,smd-edge = <0>;
+ qcom,ipc = <&apcs 8 12>;
+ qcom,remote-pid = <1>;
+ };
};
hexagon-smp2p {
diff --git a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts
new file mode 100644
index 000000000000..454213391671
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts
@@ -0,0 +1,41 @@
+/* Copyright (c) 2015, LGE Inc. All rights reserved.
+ * Copyright (c) 2016, 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.
+ */
+
+/dts-v1/;
+
+#include "msm8992.dtsi"
+
+/ {
+ model = "LG Nexus 5X";
+ compatible = "lg,bullhead", "qcom,msm8992";
+ /* required for bootloader to select correct board */
+ qcom,board-id = <0xb64 0>;
+ qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>;
+
+ aliases {
+ serial0 = &blsp1_uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ soc {
+ serial@f991e000 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&blsp1_uart2_default>;
+ pinctrl-1 = <&blsp1_uart2_sleep>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi
new file mode 100644
index 000000000000..d2a26f0f8d73
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013-2015, 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.
+ */
+
+&msmgpio {
+ blsp1_uart2_default: blsp1_uart2_default {
+ pinmux {
+ function = "blsp_uart2";
+ pins = "gpio4", "gpio5";
+ };
+ pinconf {
+ pins = "gpio4", "gpio5";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2_sleep: blsp1_uart2_sleep {
+ pinmux {
+ function = "gpio";
+ pins = "gpio4", "gpio5";
+ };
+ pinconf {
+ pins = "gpio4", "gpio5";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi
new file mode 100644
index 000000000000..44b2d37d8c4b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi
@@ -0,0 +1,184 @@
+/* Copyright (c) 2013-2016, 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-msm8994.h>
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM 8992";
+ compatible = "qcom,msm8992";
+ // msm-id needed by bootloader for selecting correct blob
+ qcom,msm-id = <251 0>, <252 0>;
+ interrupt-parent = <&intc>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen { };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ };
+ };
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ 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>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0xffffffff>;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ restart@fc4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0xfc4ab000 0x4>;
+ };
+
+ msmgpio: pinctrl@fd510000 {
+ compatible = "qcom,msm8994-pinctrl";
+ reg = <0xfd510000 0x4000>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ blsp1_uart2: serial@f991e000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf991e000 0x1000>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_LOW>;
+ status = "disabled";
+ clock-names = "core", "iface";
+ clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ };
+
+ clock_gcc: clock-controller@fc400000 {
+ compatible = "qcom,gcc-msm8994";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ reg = <0xfc400000 0x2000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0 0>; // bootloader will update
+ };
+};
+
+
+#include "msm8992-pins.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
new file mode 100644
index 000000000000..dfa08f513dc4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
@@ -0,0 +1,40 @@
+/* Copyright (c) 2015, Huawei Inc. All rights reserved.
+ * Copyright (c) 2016, 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.
+ */
+
+/dts-v1/;
+
+#include "msm8994.dtsi"
+
+/ {
+ model = "Huawei Nexus 6P";
+ compatible = "huawei,angler", "qcom,msm8994";
+ /* required for bootloader to select correct board */
+ qcom,board-id = <8026 0>;
+
+ aliases {
+ serial0 = &blsp1_uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ soc {
+ serial@f991e000 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&blsp1_uart2_default>;
+ pinctrl-1 = <&blsp1_uart2_sleep>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
new file mode 100644
index 000000000000..0e4eea0df25d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013-2016, 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.
+ */
+
+&msmgpio {
+ blsp1_uart2_default: blsp1_uart2_default {
+ pinmux {
+ function = "blsp_uart2";
+ pins = "gpio4", "gpio5";
+ };
+ pinconf {
+ pins = "gpio4", "gpio5";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2_sleep: blsp1_uart2_sleep {
+ pinmux {
+ function = "gpio";
+ pins = "gpio4", "gpio5";
+ };
+ pinconf {
+ pins = "gpio4", "gpio5";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
new file mode 100644
index 000000000000..f33c41d01c86
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -0,0 +1,216 @@
+/* Copyright (c) 2013-2016, 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 <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-msm8994.h>
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM 8994";
+ compatible = "qcom,msm8994";
+ // msm-id and pmic-id are required by bootloader for
+ // proper selection of dt blob
+ qcom,msm-id = <207 0x20000>;
+ qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>;
+ interrupt-parent = <&intc>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen { };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ };
+ };
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 2 0xff08>,
+ <1 3 0xff08>,
+ <1 4 0xff08>,
+ <1 1 0xff08>;
+ };
+
+ soc: soc {
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0xffffffff>;
+ compatible = "simple-bus";
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ restart@fc4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0xfc4ab000 0x4>;
+ };
+
+ msmgpio: pinctrl@fd510000 {
+ compatible = "qcom,msm8994-pinctrl";
+ reg = <0xfd510000 0x4000>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ blsp1_uart2: serial@f991e000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf991e000 0x1000>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-names = "core", "iface";
+ clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ };
+
+ tcsr_mutex_regs: syscon@fd484000 {
+ compatible = "syscon";
+ reg = <0xfd484000 0x2000>;
+ };
+
+ clock_gcc: clock-controller@fc400000 {
+ compatible = "qcom,gcc-msm8994";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ reg = <0xfc400000 0x2000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ // We expect the bootloader to fill in the reg
+ reg = <0 0 0 0>;
+ };
+
+ 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>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ smem_mem: smem_region@6a00000 {
+ reg = <0x0 0x6a00000 0x0 0x200000>;
+ no-map;
+ };
+ };
+
+ tcsr_mutex: hwlock {
+ compatible = "qcom,tcsr-mutex";
+ syscon = <&tcsr_mutex_regs 0 0x80>;
+ #hwlock-cells = <1>;
+ };
+
+ qcom,smem@6a00000 {
+ compatible = "qcom,smem";
+ memory-region = <&smem_mem>;
+ hwlocks = <&tcsr_mutex 3>;
+ };
+};
+
+
+#include "msm8994-pins.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 338f82a7fdc7..9d1d7ad9b075 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -30,6 +30,42 @@
reg = <0 0 0 0>;
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ mba_region: mba@91500000 {
+ reg = <0x0 0x91500000 0x0 0x200000>;
+ no-map;
+ };
+
+ slpi_region: slpi@90b00000 {
+ reg = <0x0 0x90b00000 0x0 0xa00000>;
+ no-map;
+ };
+
+ venus_region: venus@90400000 {
+ reg = <0x0 0x90400000 0x0 0x700000>;
+ no-map;
+ };
+
+ adsp_region: adsp@8ea00000 {
+ reg = <0x0 0x8ea00000 0x0 0x1a00000>;
+ no-map;
+ };
+
+ mpss_region: mpss@88800000 {
+ reg = <0x0 0x88800000 0x0 0x6200000>;
+ no-map;
+ };
+
+ smem_mem: smem-mem@86000000 {
+ reg = <0x0 0x86000000 0x0 0x200000>;
+ no-map;
+ };
+ };
+
cpus {
#address-cells = <2>;
#size-cells = <0>;
@@ -192,14 +228,14 @@
};
clocks {
- xo_board {
+ xo_board: xo_board {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <19200000>;
clock-output-names = "xo_board";
};
- sleep_clk {
+ sleep_clk: sleep_clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32764>;
@@ -212,12 +248,29 @@
method = "smc";
};
+ tcsr_mutex: hwlock {
+ compatible = "qcom,tcsr-mutex";
+ syscon = <&tcsr_mutex_regs 0 0x1000>;
+ #hwlock-cells = <1>;
+ };
+
+ smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem_mem>;
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0 0xffffffff>;
compatible = "simple-bus";
+ tcsr_mutex_regs: syscon@740000 {
+ compatible = "syscon";
+ reg = <0x740000 0x20000>;
+ };
+
intc: interrupt-controller@9bc0000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
@@ -229,6 +282,11 @@
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};
+ apcs: syscon@9820000 {
+ compatible = "syscon";
+ reg = <0x9820000 0x1000>;
+ };
+
gcc: clock-controller@300000 {
compatible = "qcom,gcc-msm8996";
#clock-cells = <1>;
@@ -347,9 +405,10 @@
interrupts = <0 125 0>, <0 221 0>;
interrupt-names = "hc_irq", "pwr_irq";
- clock-names = "iface", "core";
+ clock-names = "iface", "core", "xo";
clocks = <&gcc GCC_SDCC2_AHB_CLK>,
- <&gcc GCC_SDCC2_APPS_CLK>;
+ <&gcc GCC_SDCC2_APPS_CLK>,
+ <&xo_board>;
bus-width = <4>;
};
@@ -458,5 +517,29 @@
<825000000>;
};
};
+
+ adsp-smp2p {
+ compatible = "qcom,smp2p";
+ qcom,smem = <443>, <429>;
+
+ interrupts = <0 158 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&apcs 16 10>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <2>;
+
+ adsp_smp2p_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ #qcom,state-cells = <1>;
+ };
+
+ adsp_smp2p_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
};
#include "msm8996-pins.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
index f71679b15d54..53deebf9f515 100644
--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
@@ -91,9 +91,52 @@
};
pm8916_1: pm8916@1 {
- compatible = "qcom,spmi-pmic";
+ compatible = "qcom,pm8916", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
+
+ wcd_codec: codec@f000 {
+ compatible = "qcom,pm8916-wcd-analog-codec";
+ reg = <0xf000 0x200>;
+ reg-names = "pmic-codec-core";
+ clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
+ clock-names = "mclk";
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
+ interrupt-names = "cdc_spk_cnp_int",
+ "cdc_spk_clip_int",
+ "cdc_spk_ocp_int",
+ "mbhc_ins_rem_det1",
+ "mbhc_but_rel_det",
+ "mbhc_but_press_det",
+ "mbhc_ins_rem_det",
+ "mbhc_switch_int",
+ "cdc_ear_ocp_int",
+ "cdc_hphr_ocp_int",
+ "cdc_hphl_ocp_det",
+ "cdc_ear_cnp_int",
+ "cdc_hphr_cnp_int",
+ "cdc_hphl_cnp_int";
+ vdd-cdc-io-supply = <&pm8916_l5>;
+ vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
+ vdd-micbias-supply = <&pm8916_l13>;
+ #sound-dai-cells = <1>;
+
+ };
+
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi
index 1222d2e904f6..0f1866024ae3 100644
--- a/arch/arm64/boot/dts/qcom/pm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi
@@ -29,6 +29,7 @@
<0 0xcc 0 IRQ_TYPE_NONE>,
<0 0xcd 0 IRQ_TYPE_NONE>,
<0 0xce 0 IRQ_TYPE_NONE>,
+ <0 0xcf 0 IRQ_TYPE_NONE>,
<0 0xd0 0 IRQ_TYPE_NONE>,
<0 0xd1 0 IRQ_TYPE_NONE>,
<0 0xd2 0 IRQ_TYPE_NONE>,
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index eb72830ec9eb..1618e0a3c81d 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -1,5 +1,5 @@
dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb r8a7795-h3ulcb.dtb
-dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb
+dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb
always := $(dtb-y)
clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
index bcb11a868343..6ffb0517421a 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
@@ -1,5 +1,5 @@
/*
- * Device Tree Source for the H3ULCB board
+ * Device Tree Source for the H3ULCB (R-Car Starter Kit Premier) board
*
* Copyright (C) 2016 Renesas Electronics Corp.
* Copyright (C) 2016 Cogent Embedded, Inc.
@@ -62,6 +62,24 @@
clock-frequency = <24576000>;
};
+ reg_1p8v: regulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
vcc_sdhi0: regulator-vcc-sdhi0 {
compatible = "regulator-fixed";
@@ -145,18 +163,30 @@
function = "avb";
};
- sdhi0_pins_3v3: sd0_3v3 {
+ sdhi0_pins: sd0 {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
power-source = <3300>;
};
- sdhi0_pins_1v8: sd0_1v8 {
+ sdhi0_pins_uhs: sd0 {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
power-source = <1800>;
};
+ sdhi2_pins: sd2 {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <3300>;
+ };
+
+ sdhi2_pins_uhs: sd2_uhs {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <1800>;
+ };
+
sound_pins: sound {
groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
function = "ssi";
@@ -261,8 +291,8 @@
};
&sdhi0 {
- pinctrl-0 = <&sdhi0_pins_3v3>;
- pinctrl-1 = <&sdhi0_pins_1v8>;
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-1 = <&sdhi0_pins_uhs>;
pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi0>;
@@ -273,6 +303,19 @@
status = "okay";
};
+&sdhi2 {
+ /* used for on-board 8bit eMMC */
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-1 = <&sdhi2_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
&ssi1 {
shared-pin;
};
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
index b1eab6876f8c..bcaf4008d32d 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
@@ -62,6 +62,24 @@
clock-frequency = <24576000>;
};
+ reg_1p8v: regulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
vcc_sdhi0: regulator-vcc-sdhi0 {
compatible = "regulator-fixed";
@@ -191,6 +209,10 @@
remote-endpoint = <&adv7123_in>;
};
};
+ port@3 {
+ lvds_connector: endpoint {
+ };
+ };
};
};
@@ -237,11 +259,37 @@
sdhi0_pins: sd0 {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
+ };
+
+ sdhi2_pins: sd2 {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <3300>;
+ };
+
+ sdhi2_pins_uhs: sd2_uhs {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <1800>;
};
sdhi3_pins: sd3 {
groups = "sdhi3_data4", "sdhi3_ctrl";
function = "sdhi3";
+ power-source = <3300>;
+ };
+
+ sdhi3_pins_uhs: sd3_uhs {
+ groups = "sdhi3_data4", "sdhi3_ctrl";
+ function = "sdhi3";
+ power-source = <1800>;
};
sound_pins: sound {
@@ -261,8 +309,20 @@
};
usb1_pins: usb1 {
- groups = "usb1";
- function = "usb1";
+ mux {
+ groups = "usb1";
+ function = "usb1";
+ };
+
+ ovc {
+ pins = "GP_6_27";
+ bias-pull-up;
+ };
+
+ pwen {
+ pins = "GP_6_26";
+ bias-pull-down;
+ };
};
usb2_pins: usb2 {
@@ -371,25 +431,42 @@
&sdhi0 {
pinctrl-0 = <&sdhi0_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi0>;
vqmmc-supply = <&vccq_sdhi0>;
cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
bus-width = <4>;
+ sd-uhs-sdr50;
+ status = "okay";
+};
+
+&sdhi2 {
+ /* used for on-board 8bit eMMC */
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-1 = <&sdhi2_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ non-removable;
status = "okay";
};
&sdhi3 {
pinctrl-0 = <&sdhi3_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi3_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi3>;
vqmmc-supply = <&vccq_sdhi3>;
cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
bus-width = <4>;
+ sd-uhs-sdr50;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 625dda713548..bbf594bce930 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -326,6 +326,11 @@
reg = <0 0xe6160000 0 0x0200>;
};
+ prr: chipid@fff00044 {
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,r8a7795-sysc";
reg = <0 0xe6180000 0 0x0400>;
@@ -1311,28 +1316,28 @@
};
fcpvb1: fcp@fe92f000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfe92f000 0 0x200>;
clocks = <&cpg CPG_MOD 606>;
power-domains = <&sysc R8A7795_PD_A3VP>;
};
fcpf0: fcp@fe950000 {
- compatible = "renesas,r8a7795-fcpf", "renesas,fcpf";
+ compatible = "renesas,fcpf";
reg = <0 0xfe950000 0 0x200>;
clocks = <&cpg CPG_MOD 615>;
power-domains = <&sysc R8A7795_PD_A3VP>;
};
fcpf1: fcp@fe951000 {
- compatible = "renesas,r8a7795-fcpf", "renesas,fcpf";
+ compatible = "renesas,fcpf";
reg = <0 0xfe951000 0 0x200>;
clocks = <&cpg CPG_MOD 614>;
power-domains = <&sysc R8A7795_PD_A3VP>;
};
fcpf2: fcp@fe952000 {
- compatible = "renesas,r8a7795-fcpf", "renesas,fcpf";
+ compatible = "renesas,fcpf";
reg = <0 0xfe952000 0 0x200>;
clocks = <&cpg CPG_MOD 613>;
power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1349,7 +1354,7 @@
};
fcpvb0: fcp@fe96f000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfe96f000 0 0x200>;
clocks = <&cpg CPG_MOD 607>;
power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1366,7 +1371,7 @@
};
fcpvi0: fcp@fe9af000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfe9af000 0 0x200>;
clocks = <&cpg CPG_MOD 611>;
power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1383,7 +1388,7 @@
};
fcpvi1: fcp@fe9bf000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfe9bf000 0 0x200>;
clocks = <&cpg CPG_MOD 610>;
power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1400,7 +1405,7 @@
};
fcpvi2: fcp@fe9cf000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfe9cf000 0 0x200>;
clocks = <&cpg CPG_MOD 609>;
power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1417,7 +1422,7 @@
};
fcpvd0: fcp@fea27000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfea27000 0 0x200>;
clocks = <&cpg CPG_MOD 603>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -1434,7 +1439,7 @@
};
fcpvd1: fcp@fea2f000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfea2f000 0 0x200>;
clocks = <&cpg CPG_MOD 602>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -1451,7 +1456,7 @@
};
fcpvd2: fcp@fea37000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfea37000 0 0x200>;
clocks = <&cpg CPG_MOD 601>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -1468,7 +1473,7 @@
};
fcpvd3: fcp@fea3f000 {
- compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ compatible = "renesas,fcpv";
reg = <0 0xfea3f000 0 0x200>;
clocks = <&cpg CPG_MOD 600>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
new file mode 100644
index 000000000000..c3f064ac2cb4
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
@@ -0,0 +1,189 @@
+/*
+ * Device Tree Source for the M3ULCB (R-Car Starter Kit Pro) board
+ *
+ * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016 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 "r8a7796.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Renesas M3ULCB board based on r8a7796";
+ compatible = "renesas,m3ulcb", "renesas,r8a7796";
+
+ aliases {
+ serial0 = &scif2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led5 {
+ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+ };
+ led6 {
+ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ key-1 {
+ linux,code = <KEY_1>;
+ label = "SW3";
+ wakeup-source;
+ debounce-interval = <20>;
+ gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reg_1p8v: regulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc_sdhi0: regulator-vcc-sdhi0 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi0: regulator-vccq-sdhi0 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ scif2_pins: scif2 {
+ groups = "scif2_data_a";
+ function = "scif2";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk_a";
+ function = "scif_clk";
+ };
+
+ sdhi0_pins: sd0 {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
+ };
+
+ sdhi2_pins: sd2 {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <3300>;
+ };
+
+ sdhi2_pins_uhs: sd2_uhs {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <1800>;
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ status = "okay";
+};
+
+&sdhi2 {
+ /* used for on-board 8bit eMMC */
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-1 = <&sdhi2_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <14745600>;
+ status = "okay";
+};
+
+&wdt0 {
+ timeout-sec = <60>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
index 13db7d61c26c..f35e96ca7d60 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
@@ -10,6 +10,7 @@
/dts-v1/;
#include "r8a7796.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Renesas Salvator-X board based on r8a7796";
@@ -29,6 +30,72 @@
/* first 128MB is reserved for secure area. */
reg = <0x0 0x48000000 0x0 0x78000000>;
};
+
+ reg_1p8v: regulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc_sdhi0: regulator-vcc-sdhi0 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi0: regulator-vccq-sdhi0 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+
+ vcc_sdhi3: regulator-vcc-sdhi3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI3 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi3: regulator-vccq-sdhi3 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI3 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
};
&pfc {
@@ -43,12 +110,98 @@
groups = "scif_clk_a";
function = "scif_clk";
};
+
+ i2c2_pins: i2c2 {
+ groups = "i2c2_a";
+ function = "i2c2";
+ };
+
+ sdhi0_pins: sd0 {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
+ };
+
+ sdhi2_pins: sd2 {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <3300>;
+ };
+
+ sdhi2_pins_uhs: sd2_uhs {
+ groups = "sdhi2_data8", "sdhi2_ctrl";
+ function = "sdhi2";
+ power-source = <1800>;
+ };
+
+ sdhi3_pins: sd3 {
+ groups = "sdhi3_data4", "sdhi3_ctrl";
+ function = "sdhi3";
+ power-source = <3300>;
+ };
+
+ sdhi3_pins_uhs: sd3_uhs {
+ groups = "sdhi3_data4", "sdhi3_ctrl";
+ function = "sdhi3";
+ power-source = <1800>;
+ };
};
&extal_clk {
clock-frequency = <16666666>;
};
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ status = "okay";
+};
+
+&sdhi2 {
+ /* used for on-board 8bit eMMC */
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-1 = <&sdhi2_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&sdhi3 {
+ pinctrl-0 = <&sdhi3_pins>;
+ pinctrl-1 = <&sdhi3_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&vcc_sdhi3>;
+ vqmmc-supply = <&vccq_sdhi3>;
+ cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ status = "okay";
+};
+
&scif2 {
pinctrl-0 = <&scif2_pins>;
pinctrl-names = "default";
@@ -60,6 +213,13 @@
status = "okay";
};
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
&wdt0 {
timeout-sec = <60>;
status = "okay";
diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 75c8c55a8248..28ba59a00cd8 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -17,6 +17,16 @@
#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";
@@ -238,12 +248,118 @@
reg = <0 0xe6160000 0 0x0200>;
};
+ prr: chipid@fff00044 {
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+ };
+
sysc: system-controller@e6180000 {
compatible = "renesas,r8a7796-sysc";
reg = <0 0xe6180000 0 0x0400>;
#power-domain-cells = <1>;
};
+ i2c0: i2c@e6500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe6500000 0 0x40>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 931>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+ <&dmac2 0x91>, <&dmac2 0x90>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6508000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 930>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+ <&dmac2 0x93>, <&dmac2 0x92>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6510000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe6510000 0 0x40>;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 929>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+ <&dmac2 0x95>, <&dmac2 0x94>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e66d0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe66d0000 0 0x40>;
+ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 928>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e66d8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe66d8000 0 0x40>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 927>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac0 0x99>, <&dmac0 0x98>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@e66e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe66e0000 0 0x40>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 919>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@e66e8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7796";
+ reg = <0 0xe66e8000 0 0x40>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 918>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
+ dma-names = "tx", "rx";
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
scif2: serial@e6e88000 {
compatible = "renesas,scif-r8a7796",
"renesas,rcar-gen3-scif", "renesas,scif";
@@ -256,5 +372,144 @@
power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
status = "disabled";
};
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,dmac-r8a7796",
+ "renesas,rcar-dmac";
+ reg = <0 0xe6700000 0 0x10000>;
+ interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 215 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 219>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a7796",
+ "renesas,rcar-dmac";
+ reg = <0 0xe7300000 0 0x10000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 319 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 218>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ dmac2: dma-controller@e7310000 {
+ compatible = "renesas,dmac-r8a7796",
+ "renesas,rcar-dmac";
+ reg = <0 0xe7310000 0 0x10000>;
+ interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 397 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 217>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ sdhi0: sd@ee100000 {
+ compatible = "renesas,sdhi-r8a7796";
+ reg = <0 0xee100000 0 0x2000>;
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 314>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ sdhi1: sd@ee120000 {
+ compatible = "renesas,sdhi-r8a7796";
+ reg = <0 0xee120000 0 0x2000>;
+ interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 313>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ sdhi2: sd@ee140000 {
+ compatible = "renesas,sdhi-r8a7796";
+ reg = <0 0xee140000 0 0x2000>;
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 312>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
+ sdhi3: sd@ee160000 {
+ compatible = "renesas,sdhi-r8a7796";
+ reg = <0 0xee160000 0 0x2000>;
+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 311>;
+ max-frequency = <200000000>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 87669f656454..3a862894ea44 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -1,6 +1,7 @@
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
index ea0a8eceefd4..ff5a40399d02 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
@@ -344,7 +344,7 @@
&sdmmc {
bus-width = <4>;
clock-frequency = <50000000>;
- clock-freq-min-max = <400000 50000000>;
+ max-frequency = <50000000>;
cap-sd-highspeed;
card-detect-delay = <200>;
num-slots = <1>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts
new file mode 100644
index 000000000000..85f7a243d744
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., 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.
+ *
+ * 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.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Rockchip PX5 EVB";
+ compatible = "rockchip,px5-evb", "rockchip,px5", "rockchip,rk3368";
+
+ chosen {
+ stdout-path = "serial4:115200n8";
+ };
+
+ memory@0 {
+ reg = <0x0 0x0 0x0 0x80000000>;
+ device_type = "memory";
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+
+ power {
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <KEY_POWER>;
+ wakeup-source;
+ };
+ };
+
+ 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 {
+ status = "okay";
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ clock-frequency = <150000000>;
+ disable-wp;
+ keep-power-in-suspend;
+ mmc-hs200-1_8v;
+ no-sdio;
+ no-sd;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc18_flash>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int>, <&pmic_sleep>;
+ rockchip,system-power-controller;
+ 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_io>;
+ vcc9-supply = <&vcc_sys>;
+ vcc10-supply = <&vcc_sys>;
+ vcc11-supply = <&vcc_sys>;
+ vcc12-supply = <&vcc_io>;
+ clock-output-names = "xin32k", "rk808-clkout2";
+ #clock-cells = <1>;
+
+ regulators {
+ vdd_cpu: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vdd_cpu";
+ };
+
+ vdd_log: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vdd_log";
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_ddr";
+ };
+
+ vcc_io: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_io";
+ };
+
+ vcc18_flash: LDO_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc18_flash";
+ };
+
+ vcca_33: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcca_33";
+ };
+
+ vdd_10: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd_10";
+ };
+
+ avdd_33: LDO_REG4 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avdd_33";
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd";
+ };
+
+ vdd10_lcd: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd10_lcd";
+ };
+
+ vcc_18: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_18";
+ };
+
+ vcc18_lcd: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc18_lcd";
+ };
+
+ vcc_sd: SWITCH_REG1 {
+ regulator-name = "vcc_sd";
+ };
+
+ vcc33_lcd: SWITCH_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc33_lcd";
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ accelerometer@18 {
+ compatible = "bosch,bma250";
+ reg = <0x18>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ gsl1680: touchscreen@40 {
+ compatible = "silead,gsl1680";
+ reg = <0x40>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <28 IRQ_TYPE_EDGE_FALLING>;
+ power-gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <1280>;
+ silead,max-fingers = <5>;
+ };
+};
+
+&pinctrl {
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <0 2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_sleep: pmic-sleep {
+ rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ pmic_int: pmic-int {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&sdmmc {
+ status = "okay";
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ no-emmc;
+ no-sdio;
+ num-slots = <1>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_bus4>, <&sdmmc_cd>;
+ rockchip,default-sample-phase = <90>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+};
+
+&tsadc {
+ status = "okay";
+ rockchip,hw-tshut-mode = <0>; /* CRU */
+ rockchip,hw-tshut-polarity = <1>; /* high */
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
index df231c4df5a5..a635adc47e74 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -231,7 +231,7 @@
sdmmc: dwmmc@ff0c0000 {
compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xff0c0000 0x0 0x4000>;
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -243,7 +243,7 @@
sdio0: dwmmc@ff0d0000 {
compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xff0d0000 0x0 0x4000>;
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
<&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
@@ -255,7 +255,7 @@
emmc: dwmmc@ff0f0000 {
compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xff0f0000 0x0 0x4000>;
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
<&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -315,16 +315,16 @@
status = "disabled";
};
- i2c1: i2c@ff140000 {
+ i2c2: i2c@ff140000 {
compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
reg = <0x0 0xff140000 0x0 0x1000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clock-names = "i2c";
- clocks = <&cru PCLK_I2C1>;
+ clocks = <&cru PCLK_I2C2>;
pinctrl-names = "default";
- pinctrl-0 = <&i2c1_xfer>;
+ pinctrl-0 = <&i2c2_xfer>;
status = "disabled";
};
@@ -553,16 +553,16 @@
status = "disabled";
};
- i2c2: i2c@ff660000 {
+ i2c1: i2c@ff660000 {
compatible = "rockchip,rk3368-i2c", "rockchip,rk3288-i2c";
reg = <0x0 0xff660000 0x0 0x1000>;
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clock-names = "i2c";
- clocks = <&cru PCLK_I2C2>;
+ clocks = <&cru PCLK_I2C1>;
pinctrl-names = "default";
- pinctrl-0 = <&i2c2_xfer>;
+ pinctrl-0 = <&i2c1_xfer>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts
index 8e82497925fe..3040a989d699 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts
@@ -49,6 +49,46 @@
compatible = "rockchip,rk3399-evb", "rockchip,rk3399",
"google,rk3399evb-rev2";
+ 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 = <200>;
+ enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ pwms = <&pwm0 0 25000 0>;
+ };
+
clkin_gmac: external-gmac-clock {
compatible = "fixed-clock";
clock-frequency = <125000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 1e24e455700b..c928015d39a2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -236,7 +236,7 @@
"rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe310000 0x0 0x4000>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH 0>;
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
<&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
@@ -249,11 +249,12 @@
"rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe320000 0x0 0x4000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
- clock-freq-min-max = <400000 150000000>;
+ max-frequency = <150000000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
+ power-domains = <&power RK3399_PD_SD>;
status = "disabled";
};
@@ -270,6 +271,7 @@
#clock-cells = <0>;
phys = <&emmc_phy>;
phy-names = "phy_arasan";
+ power-domains = <&power RK3399_PD_EMMC>;
status = "disabled";
};
@@ -694,6 +696,16 @@
status = "disabled";
};
+ qos_sd: qos@ffa74000 {
+ compatible = "syscon";
+ reg = <0x0 0xffa74000 0x0 0x20>;
+ };
+
+ qos_emmc: qos@ffa58000 {
+ compatible = "syscon";
+ reg = <0x0 0xffa58000 0x0 0x20>;
+ };
+
qos_gmac: qos@ffa5c000 {
compatible = "syscon";
reg = <0x0 0xffa5c000 0x0 0x20>;
@@ -827,11 +839,23 @@
};
/* These power domains are grouped by VD_LOGIC */
+ pd_emmc@RK3399_PD_EMMC {
+ reg = <RK3399_PD_EMMC>;
+ clocks = <&cru ACLK_EMMC>;
+ pm_qos = <&qos_emmc>;
+ };
pd_gmac@RK3399_PD_GMAC {
reg = <RK3399_PD_GMAC>;
- clocks = <&cru ACLK_GMAC>;
+ clocks = <&cru ACLK_GMAC>,
+ <&cru PCLK_GMAC>;
pm_qos = <&qos_gmac>;
};
+ pd_sd@RK3399_PD_SD {
+ reg = <RK3399_PD_SD>;
+ clocks = <&cru HCLK_SDMMC>,
+ <&cru SCLK_SDMMC>;
+ pm_qos = <&qos_sd>;
+ };
pd_vio@RK3399_PD_VIO {
reg = <RK3399_PD_VIO>;
#address-cells = <1>;
@@ -1027,6 +1051,9 @@
clock-names = "pclk_efuse";
/* Data cells */
+ cpu_id: cpu-id@7 {
+ reg = <0x07 0x10>;
+ };
cpub_leakage: cpu-leakage@17 {
reg = <0x17 0x1>;
};
@@ -1105,6 +1132,16 @@
interrupt-names = "linestate";
status = "disabled";
};
+
+ u2phy0_otg: otg-port {
+ #phy-cells = <0>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+ status = "disabled";
+ };
};
u2phy1: usb2-phy@e460 {
@@ -1122,6 +1159,16 @@
interrupt-names = "linestate";
status = "disabled";
};
+
+ u2phy1_otg: otg-port {
+ #phy-cells = <0>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+ status = "disabled";
+ };
};
emmc_phy: phy@f780 {
@@ -1152,6 +1199,7 @@
clock-names = "tcpdcore", "tcpdphy-ref";
assigned-clocks = <&cru SCLK_UPHY0_TCPDCORE>;
assigned-clock-rates = <50000000>;
+ power-domains = <&power RK3399_PD_TCPD0>;
resets = <&cru SRST_UPHY0>,
<&cru SRST_UPHY0_PIPE_L00>,
<&cru SRST_P_UPHY0_TCPHY>;
@@ -1180,6 +1228,7 @@
clock-names = "tcpdcore", "tcpdphy-ref";
assigned-clocks = <&cru SCLK_UPHY1_TCPDCORE>;
assigned-clock-rates = <50000000>;
+ power-domains = <&power RK3399_PD_TCPD1>;
resets = <&cru SRST_UPHY1>,
<&cru SRST_UPHY1_PIPE_L00>,
<&cru SRST_P_UPHY1_TCPHY>;
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
index 3eb4c42ce7b9..7c7511b9d231 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/memreserve/ 0x80000000 0x00000008; /* cpu-release-addr */
+/memreserve/ 0x80000000 0x00080000;
/ {
compatible = "socionext,uniphier-ld11";
@@ -70,19 +70,60 @@
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0 0x000>;
- enable-method = "spin-table";
- cpu-release-addr = <0 0x80000000>;
+ clocks = <&sys_clk 33>;
+ enable-method = "psci";
+ operating-points-v2 = <&cluster0_opp>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0 0x001>;
- enable-method = "spin-table";
- cpu-release-addr = <0 0x80000000>;
+ clocks = <&sys_clk 33>;
+ enable-method = "psci";
+ operating-points-v2 = <&cluster0_opp>;
};
};
+ cluster0_opp: opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@245000000 {
+ opp-hz = /bits/ 64 <245000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@490000000 {
+ opp-hz = /bits/ 64 <490000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@653334000 {
+ opp-hz = /bits/ 64 <653334000>;
+ clock-latency-ns = <300>;
+ };
+ opp@666667000 {
+ opp-hz = /bits/ 64 <666667000>;
+ clock-latency-ns = <300>;
+ };
+ opp@980000000 {
+ opp-hz = /bits/ 64 <980000000>;
+ clock-latency-ns = <300>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
clocks {
refclk: ref {
compatible = "fixed-clock";
@@ -233,7 +274,7 @@
};
perictrl@59820000 {
- compatible = "socionext,uniphier-perictrl",
+ compatible = "socionext,uniphier-ld11-perictrl",
"simple-mfd", "syscon";
reg = <0x59820000 0x200>;
@@ -282,7 +323,7 @@
};
mioctrl@5b3e0000 {
- compatible = "socionext,uniphier-mioctrl",
+ compatible = "socionext,uniphier-ld11-mioctrl",
"simple-mfd", "syscon";
reg = <0x5b3e0000 0x800>;
@@ -299,7 +340,7 @@
};
soc-glue@5f800000 {
- compatible = "socionext,uniphier-soc-glue",
+ compatible = "socionext,uniphier-ld11-soc-glue",
"simple-mfd", "syscon";
reg = <0x5f800000 0x2000>;
@@ -320,7 +361,7 @@
sysctrl@61840000 {
compatible = "socionext,uniphier-ld11-sysctrl",
"simple-mfd", "syscon";
- reg = <0x61840000 0x4000>;
+ reg = <0x61840000 0x10000>;
sys_clk: clock {
compatible = "socionext,uniphier-ld11-clock";
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
index 56a1b2e92cf3..fcaecc6bdeac 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
@@ -43,7 +43,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/memreserve/ 0x80000000 0x00000008; /* cpu-release-addr */
+/memreserve/ 0x80000000 0x00080000;
/ {
compatible = "socionext,uniphier-ld20";
@@ -79,35 +79,120 @@
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
reg = <0 0x000>;
- enable-method = "spin-table";
- cpu-release-addr = <0 0x80000000>;
+ clocks = <&sys_clk 32>;
+ enable-method = "psci";
+ operating-points-v2 = <&cluster0_opp>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
reg = <0 0x001>;
- enable-method = "spin-table";
- cpu-release-addr = <0 0x80000000>;
+ clocks = <&sys_clk 32>;
+ enable-method = "psci";
+ operating-points-v2 = <&cluster0_opp>;
};
cpu2: cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0 0x100>;
- enable-method = "spin-table";
- cpu-release-addr = <0 0x80000000>;
+ clocks = <&sys_clk 33>;
+ enable-method = "psci";
+ operating-points-v2 = <&cluster1_opp>;
};
cpu3: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0 0x101>;
- enable-method = "spin-table";
- cpu-release-addr = <0 0x80000000>;
+ clocks = <&sys_clk 33>;
+ enable-method = "psci";
+ operating-points-v2 = <&cluster1_opp>;
};
};
+ cluster0_opp: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@275000000 {
+ opp-hz = /bits/ 64 <275000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@550000000 {
+ opp-hz = /bits/ 64 <550000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@666667000 {
+ opp-hz = /bits/ 64 <666667000>;
+ clock-latency-ns = <300>;
+ };
+ opp@733334000 {
+ opp-hz = /bits/ 64 <733334000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ clock-latency-ns = <300>;
+ };
+ };
+
+ cluster1_opp: opp_table1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp@250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@275000000 {
+ opp-hz = /bits/ 64 <275000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@550000000 {
+ opp-hz = /bits/ 64 <550000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@666667000 {
+ opp-hz = /bits/ 64 <666667000>;
+ clock-latency-ns = <300>;
+ };
+ opp@733334000 {
+ opp-hz = /bits/ 64 <733334000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ clock-latency-ns = <300>;
+ };
+ opp@1100000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ clock-latency-ns = <300>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
clocks {
refclk: ref {
compatible = "fixed-clock";
@@ -274,7 +359,7 @@
};
perictrl@59820000 {
- compatible = "socionext,uniphier-perictrl",
+ compatible = "socionext,uniphier-ld20-perictrl",
"simple-mfd", "syscon";
reg = <0x59820000 0x200>;
@@ -290,7 +375,7 @@
};
soc-glue@5f800000 {
- compatible = "socionext,uniphier-soc-glue",
+ compatible = "socionext,uniphier-ld20-soc-glue",
"simple-mfd", "syscon";
reg = <0x5f800000 0x2000>;
@@ -309,9 +394,9 @@
};
sysctrl@61840000 {
- compatible = "socionext,uniphier-sysctrl",
+ compatible = "socionext,uniphier-ld20-sysctrl",
"simple-mfd", "syscon";
- reg = <0x61840000 0x4000>;
+ reg = <0x61840000 0x10000>;
sys_clk: clock {
compatible = "socionext,uniphier-ld20-clock";
diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi
index a223066f24ce..88ff70a06086 100644
--- a/arch/arm64/boot/dts/zte/zx296718.dtsi
+++ b/arch/arm64/boot/dts/zte/zx296718.dtsi
@@ -239,16 +239,9 @@
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
#address-cells = <0>;
- #redistributor-regions = <6>;
- redistributor-stride = <0x0 0x40000>;
interrupt-controller;
reg = <0x02a00000 0x10000>,
- <0x02b00000 0x20000>,
- <0x02b20000 0x20000>,
- <0x02b40000 0x20000>,
- <0x02b60000 0x20000>,
- <0x02b80000 0x20000>,
- <0x02ba0000 0x20000>;
+ <0x02b00000 0xc0000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -284,9 +277,33 @@
dma-requests = <32>;
};
+ lsp0crm: clock-controller@1420000 {
+ compatible = "zte,zx296718-lsp0crm";
+ reg = <0x01420000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ lsp1crm: clock-controller@1430000 {
+ compatible = "zte,zx296718-lsp1crm";
+ reg = <0x01430000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ topcrm: clock-controller@1461000 {
+ compatible = "zte,zx296718-topcrm";
+ reg = <0x01461000 0x1000>;
+ #clock-cells = <1>;
+ };
+
sysctrl: sysctrl@1463000 {
compatible = "zte,zx296718-sysctrl", "syscon";
reg = <0x1463000 0x1000>;
};
+
+ audiocrm: clock-controller@1480000 {
+ compatible = "zte,zx296718-audiocrm";
+ reg = <0x01480000 0x1000>;
+ #clock-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c3caaddde6cc..869dded0f09f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -11,7 +11,6 @@ CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_BLK_CGROUP=y
@@ -34,6 +33,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_ALPINE=y
+CONFIG_ARCH_BCM2835=y
CONFIG_ARCH_BCM_IPROC=y
CONFIG_ARCH_BERLIN=y
CONFIG_ARCH_EXYNOS=y
@@ -148,6 +148,7 @@ CONFIG_MTD_SPI_NOR=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
CONFIG_VIRTIO_BLK=y
+CONFIG_EEPROM_AT25=m
CONFIG_SRAM=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
@@ -184,7 +185,10 @@ CONFIG_SMC91X=y
CONFIG_SMSC911X=y
CONFIG_STMMAC_ETH=m
CONFIG_REALTEK_PHY=m
+CONFIG_MESON_GXL_PHY=m
CONFIG_MICREL_PHY=y
+CONFIG_MDIO_BUS_MUX=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
@@ -195,6 +199,7 @@ CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
+CONFIG_BRCMFMAC=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SDIO=m
CONFIG_INPUT_EVDEV=y
@@ -207,6 +212,9 @@ CONFIG_SERIO_AMBAKMI=y
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_BCM2835AUX=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_8250_UNIPHIER=y
@@ -230,17 +238,21 @@ CONFIG_VIRTIO_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_BCM2835=m
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_IMX=y
CONFIG_I2C_MESON=y
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_QUP=y
+CONFIG_I2C_RK3X=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SPI=y
CONFIG_SPI_MESON_SPIFC=m
+CONFIG_SPI_BCM2835=m
+CONFIG_SPI_BCM2835AUX=m
CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_QUP=y
@@ -250,10 +262,10 @@ CONFIG_SPMI=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_MSM8916=y
+CONFIG_PINCTRL_MSM8994=y
CONFIG_PINCTRL_MSM8996=y
CONFIG_PINCTRL_QDF2XXX=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
-CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_DWAPB=y
CONFIG_GPIO_PL061=y
CONFIG_GPIO_RCAR=y
@@ -273,13 +285,16 @@ CONFIG_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
+CONFIG_BCM2835_THERMAL=y
CONFIG_EXYNOS_THERMAL=y
CONFIG_WATCHDOG=y
+CONFIG_BCM2835_WDT=y
CONFIG_RENESAS_WDT=y
CONFIG_S3C2410_WATCHDOG=y
CONFIG_MESON_GXBB_WATCHDOG=m
CONFIG_MESON_WATCHDOG=m
CONFIG_MFD_MAX77620=y
+CONFIG_MFD_RK808=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_HI655X_PMIC=y
@@ -293,10 +308,26 @@ CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_QCOM_SMD_RPM=y
CONFIG_REGULATOR_QCOM_SPMI=y
+CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_S2MPS11=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_DVB_NET is not set
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_FCP=m
+CONFIG_VIDEO_RENESAS_VSP1=m
CONFIG_DRM=m
CONFIG_DRM_NOUVEAU=m
+CONFIG_DRM_RCAR_DU=m
+CONFIG_DRM_RCAR_HDMI=y
+CONFIG_DRM_RCAR_LVDS=y
+CONFIG_DRM_RCAR_VSP=y
CONFIG_DRM_TEGRA=m
+CONFIG_DRM_VC4=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_I2C_ADV7511=m
CONFIG_DRM_HISI_KIRIN=m
@@ -311,6 +342,7 @@ CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
+CONFIG_SND_BCM2835_SOC_I2S=m
CONFIG_SND_SOC_RCAR=y
CONFIG_SND_SOC_SAMSUNG=y
CONFIG_SND_SOC_AK4613=y
@@ -343,9 +375,11 @@ CONFIG_USB_RENESAS_USBHS_UDC=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_MESON_GX=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ACPI=y
CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SDHCI_MSM=y
@@ -354,6 +388,7 @@ CONFIG_MMC_SDHI=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_K3=y
+CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SUNXI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -369,11 +404,13 @@ CONFIG_RTC_DRV_DS3232=y
CONFIG_RTC_DRV_EFI=y
CONFIG_RTC_DRV_PL031=y
CONFIG_RTC_DRV_SUN6I=y
+CONFIG_RTC_DRV_RK808=m
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_XGENE=y
CONFIG_RTC_DRV_S3C=y
CONFIG_DMADEVICES=y
CONFIG_PL330_DMA=y
+CONFIG_DMA_BCM2835=m
CONFIG_TEGRA20_APB_DMA=y
CONFIG_QCOM_BAM_DMA=y
CONFIG_QCOM_HIDMA_MGMT=y
@@ -389,26 +426,39 @@ CONFIG_XEN_GRANT_DEV_ALLOC=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMMON_CLK_CS2000_CP=y
CONFIG_COMMON_CLK_S2MPS11=y
+CONFIG_COMMON_CLK_PWM=y
+CONFIG_COMMON_CLK_RK808=y
CONFIG_CLK_QORIQ=y
CONFIG_COMMON_CLK_QCOM=y
CONFIG_MSM_GCC_8916=y
+CONFIG_MSM_GCC_8994=y
CONFIG_MSM_MMCC_8996=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_MAILBOX=y
CONFIG_ARM_MHU=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_BCM2835_MBOX=y
CONFIG_HI6220_MBOX=y
CONFIG_ARM_SMMU=y
+CONFIG_RASPBERRYPI_POWER=y
CONFIG_QCOM_SMEM=y
CONFIG_QCOM_SMD=y
CONFIG_QCOM_SMD_RPM=y
+CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
+CONFIG_ARCH_TEGRA_186_SOC=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_PWM=y
+CONFIG_PWM_BCM2835=m
+CONFIG_PWM_ROCKCHIP=y
CONFIG_PWM_TEGRA=m
+CONFIG_PWM_MESON=m
CONFIG_COMMON_RESET_HI6220=y
CONFIG_PHY_RCAR_GEN3_USB2=y
CONFIG_PHY_HI6220_USB=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_EMMC=y
CONFIG_PHY_XGENE=y
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_ARM_SCPI_PROTOCOL=y
@@ -416,6 +466,7 @@ CONFIG_ACPI=y
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
CONFIG_PWM_SAMSUNG=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index acf38722457b..4f0e3ebfea4b 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -114,6 +114,19 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
return 0;
}
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
+{
+ struct resource_entry *entry, *tmp;
+ int status;
+
+ status = acpi_pci_probe_root_resources(ci);
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+ if (!(entry->res->flags & IORESOURCE_WINDOW))
+ resource_list_destroy_entry(entry);
+ }
+ return status;
+}
+
/*
* Lookup the bus range for the domain in MCFG, and set up config space
* mapping.
@@ -121,31 +134,33 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
static struct pci_config_window *
pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
{
+ struct device *dev = &root->device->dev;
struct resource *bus_res = &root->secondary;
u16 seg = root->segment;
- struct pci_config_window *cfg;
+ struct pci_ecam_ops *ecam_ops;
struct resource cfgres;
- unsigned int bsz;
-
- /* Use address from _CBA if present, otherwise lookup MCFG */
- if (!root->mcfg_addr)
- root->mcfg_addr = pci_mcfg_lookup(seg, bus_res);
+ struct acpi_device *adev;
+ struct pci_config_window *cfg;
+ int ret;
- if (!root->mcfg_addr) {
- dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n",
- seg, bus_res);
+ ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
+ if (ret) {
+ dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res);
return NULL;
}
- bsz = 1 << pci_generic_ecam_ops.bus_shift;
- cfgres.start = root->mcfg_addr + bus_res->start * bsz;
- cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1;
- cfgres.flags = IORESOURCE_MEM;
- cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res,
- &pci_generic_ecam_ops);
+ adev = acpi_resource_consumer(&cfgres);
+ if (adev)
+ dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres,
+ dev_name(&adev->dev));
+ else
+ dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n",
+ &cfgres);
+
+ cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
if (IS_ERR(cfg)) {
- dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n",
- seg, bus_res, PTR_ERR(cfg));
+ dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res,
+ PTR_ERR(cfg));
return NULL;
}
@@ -159,33 +174,37 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
ri = container_of(ci, struct acpi_pci_generic_root_info, common);
pci_ecam_free(ri->cfg);
+ kfree(ci->ops);
kfree(ri);
}
-static struct acpi_pci_root_ops acpi_pci_root_ops = {
- .release_info = pci_acpi_generic_release_info,
-};
-
/* Interface called from ACPI code to setup PCI host controller */
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
int node = acpi_get_node(root->device->handle);
struct acpi_pci_generic_root_info *ri;
struct pci_bus *bus, *child;
+ struct acpi_pci_root_ops *root_ops;
ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
if (!ri)
return NULL;
+ root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
+ if (!root_ops)
+ return NULL;
+
ri->cfg = pci_acpi_setup_ecam_mapping(root);
if (!ri->cfg) {
kfree(ri);
+ kfree(root_ops);
return NULL;
}
- acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops;
- bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common,
- ri->cfg);
+ root_ops->release_info = pci_acpi_generic_release_info;
+ root_ops->prepare_resources = pci_acpi_root_prepare_resources;
+ root_ops->pci_ops = &ri->cfg->ops->pci_ops;
+ bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
if (!bus)
return NULL;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index aa6c8f834d9e..290a84f3351f 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -796,6 +796,8 @@ static struct dma_map_ops iommu_dma_ops = {
.sync_single_for_device = __iommu_sync_single_for_device,
.sync_sg_for_cpu = __iommu_sync_sg_for_cpu,
.sync_sg_for_device = __iommu_sync_sg_for_device,
+ .map_resource = iommu_dma_map_resource,
+ .unmap_resource = iommu_dma_unmap_resource,
.dma_supported = iommu_dma_supported,
.mapping_error = iommu_dma_mapping_error,
};
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index 32e36b16773f..c05cef6ee06c 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -54,7 +54,7 @@ DEFINE_EVENT(ppc64_interrupt_class, timer_interrupt_exit,
);
#ifdef CONFIG_PPC_PSERIES
-extern void hcall_tracepoint_regfunc(void);
+extern int hcall_tracepoint_regfunc(void);
extern void hcall_tracepoint_unregfunc(void);
TRACE_EVENT_FN_COND(hcall_entry,
@@ -104,7 +104,7 @@ TRACE_EVENT_FN_COND(hcall_exit,
#endif
#ifdef CONFIG_PPC_POWERNV
-extern void opal_tracepoint_regfunc(void);
+extern int opal_tracepoint_regfunc(void);
extern void opal_tracepoint_unregfunc(void);
TRACE_EVENT_FN(opal_entry,
diff --git a/arch/powerpc/platforms/powernv/opal-tracepoints.c b/arch/powerpc/platforms/powernv/opal-tracepoints.c
index 1e496b780efd..3c447002edff 100644
--- a/arch/powerpc/platforms/powernv/opal-tracepoints.c
+++ b/arch/powerpc/platforms/powernv/opal-tracepoints.c
@@ -6,9 +6,10 @@
#ifdef HAVE_JUMP_LABEL
struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
-void opal_tracepoint_regfunc(void)
+int opal_tracepoint_regfunc(void)
{
static_key_slow_inc(&opal_tracepoint_key);
+ return 0;
}
void opal_tracepoint_unregfunc(void)
@@ -25,9 +26,10 @@ void opal_tracepoint_unregfunc(void)
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
extern long opal_tracepoint_refcount;
-void opal_tracepoint_regfunc(void)
+int opal_tracepoint_regfunc(void)
{
opal_tracepoint_refcount++;
+ return 0;
}
void opal_tracepoint_unregfunc(void)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index f2c98f6c1c9c..a78da511ffeb 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -661,9 +661,10 @@ EXPORT_SYMBOL(arch_free_page);
#ifdef HAVE_JUMP_LABEL
struct static_key hcall_tracepoint_key = STATIC_KEY_INIT;
-void hcall_tracepoint_regfunc(void)
+int hcall_tracepoint_regfunc(void)
{
static_key_slow_inc(&hcall_tracepoint_key);
+ return 0;
}
void hcall_tracepoint_unregfunc(void)
@@ -680,9 +681,10 @@ void hcall_tracepoint_unregfunc(void)
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
extern long hcall_tracepoint_refcount;
-void hcall_tracepoint_regfunc(void)
+int hcall_tracepoint_regfunc(void)
{
hcall_tracepoint_refcount++;
+ return 0;
}
void hcall_tracepoint_unregfunc(void)
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index acc0c6f36f3f..701d29f8e4d3 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -926,8 +926,8 @@ ftrace_graph_call:
jmp ftrace_stub
#endif
-.globl ftrace_stub
-ftrace_stub:
+/* This is weak to keep gas from relaxing the jumps */
+WEAK(ftrace_stub)
ret
END(ftrace_caller)
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
index 2fbc66c7885b..2422b14c50a7 100644
--- a/arch/x86/include/asm/trace/exceptions.h
+++ b/arch/x86/include/asm/trace/exceptions.h
@@ -6,7 +6,7 @@
#include <linux/tracepoint.h>
-extern void trace_irq_vector_regfunc(void);
+extern int trace_irq_vector_regfunc(void);
extern void trace_irq_vector_unregfunc(void);
DECLARE_EVENT_CLASS(x86_exceptions,
diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h
index 38a09a13a9bc..32dd6a9e343c 100644
--- a/arch/x86/include/asm/trace/irq_vectors.h
+++ b/arch/x86/include/asm/trace/irq_vectors.h
@@ -6,7 +6,7 @@
#include <linux/tracepoint.h>
-extern void trace_irq_vector_regfunc(void);
+extern int trace_irq_vector_regfunc(void);
extern void trace_irq_vector_unregfunc(void);
DECLARE_EVENT_CLASS(x86_irq_vector,
diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c
index 1c113db9ed57..15515132bf0d 100644
--- a/arch/x86/kernel/tracepoint.c
+++ b/arch/x86/kernel/tracepoint.c
@@ -34,7 +34,7 @@ static void switch_idt(void *arg)
local_irq_restore(flags);
}
-void trace_irq_vector_regfunc(void)
+int trace_irq_vector_regfunc(void)
{
mutex_lock(&irq_vector_mutex);
if (!trace_irq_vector_refcount) {
@@ -44,6 +44,7 @@ void trace_irq_vector_regfunc(void)
}
trace_irq_vector_refcount++;
mutex_unlock(&irq_vector_mutex);
+ return 0;
}
void trace_irq_vector_unregfunc(void)
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index fd76b5fc3b3a..d3a989e718f5 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -121,6 +121,7 @@ int public_key_verify_signature(const struct public_key *pkey,
if (ret)
goto error_free_req;
+ ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
output = kmalloc(outlen, GFP_KERNEL);
if (!output)
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index aca07c643d41..0e1e6c35188e 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -226,7 +226,9 @@ static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
void *v;
if (!phys) {
- buffer = walk->buffer ?: walk->page;
+ if (!walk->buffer)
+ walk->buffer = walk->page;
+ buffer = walk->buffer;
if (buffer)
goto ok;
}
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6b81746cd13c..e0d2e6e6e40c 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -19,8 +19,17 @@
#define pr_fmt(fmt) "ACPI: IORT: " fmt
#include <linux/acpi_iort.h>
+#include <linux/iommu.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define IORT_TYPE_MASK(type) (1 << (type))
+#define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP)
+#define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) | \
+ (1 << ACPI_IORT_NODE_SMMU_V3))
struct iort_its_msi_chip {
struct list_head list;
@@ -28,6 +37,90 @@ struct iort_its_msi_chip {
u32 translation_id;
};
+struct iort_fwnode {
+ struct list_head list;
+ struct acpi_iort_node *iort_node;
+ struct fwnode_handle *fwnode;
+};
+static LIST_HEAD(iort_fwnode_list);
+static DEFINE_SPINLOCK(iort_fwnode_lock);
+
+/**
+ * iort_set_fwnode() - Create iort_fwnode and use it to register
+ * iommu data in the iort_fwnode_list
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @fwnode: fwnode associated with the IORT node
+ *
+ * Returns: 0 on success
+ * <0 on failure
+ */
+static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
+ struct fwnode_handle *fwnode)
+{
+ struct iort_fwnode *np;
+
+ np = kzalloc(sizeof(struct iort_fwnode), GFP_ATOMIC);
+
+ if (WARN_ON(!np))
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&np->list);
+ np->iort_node = iort_node;
+ np->fwnode = fwnode;
+
+ spin_lock(&iort_fwnode_lock);
+ list_add_tail(&np->list, &iort_fwnode_list);
+ spin_unlock(&iort_fwnode_lock);
+
+ return 0;
+}
+
+/**
+ * iort_get_fwnode() - Retrieve fwnode associated with an IORT node
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: fwnode_handle pointer on success, NULL on failure
+ */
+static inline
+struct fwnode_handle *iort_get_fwnode(struct acpi_iort_node *node)
+{
+ struct iort_fwnode *curr;
+ struct fwnode_handle *fwnode = NULL;
+
+ spin_lock(&iort_fwnode_lock);
+ list_for_each_entry(curr, &iort_fwnode_list, list) {
+ if (curr->iort_node == node) {
+ fwnode = curr->fwnode;
+ break;
+ }
+ }
+ spin_unlock(&iort_fwnode_lock);
+
+ return fwnode;
+}
+
+/**
+ * iort_delete_fwnode() - Delete fwnode associated with an IORT node
+ *
+ * @node: IORT table node associated with fwnode to delete
+ */
+static inline void iort_delete_fwnode(struct acpi_iort_node *node)
+{
+ struct iort_fwnode *curr, *tmp;
+
+ spin_lock(&iort_fwnode_lock);
+ list_for_each_entry_safe(curr, tmp, &iort_fwnode_list, list) {
+ if (curr->iort_node == node) {
+ list_del(&curr->list);
+ kfree(curr);
+ break;
+ }
+ }
+ spin_unlock(&iort_fwnode_lock);
+}
+
typedef acpi_status (*iort_find_node_callback)
(struct acpi_iort_node *node, void *context);
@@ -141,6 +234,21 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
return NULL;
}
+static acpi_status
+iort_match_type_callback(struct acpi_iort_node *node, void *context)
+{
+ return AE_OK;
+}
+
+bool iort_node_match(u8 type)
+{
+ struct acpi_iort_node *node;
+
+ node = iort_scan_node(type, iort_match_type_callback, NULL);
+
+ return node != NULL;
+}
+
static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
void *context)
{
@@ -212,9 +320,48 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
return 0;
}
+static
+struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
+ u32 *id_out, u8 type_mask,
+ int index)
+{
+ struct acpi_iort_node *parent;
+ struct acpi_iort_id_mapping *map;
+
+ if (!node->mapping_offset || !node->mapping_count ||
+ index >= node->mapping_count)
+ return NULL;
+
+ map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+ node->mapping_offset);
+
+ /* Firmware bug! */
+ if (!map->output_reference) {
+ pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+ node, node->type);
+ return NULL;
+ }
+
+ parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+ map->output_reference);
+
+ if (!(IORT_TYPE_MASK(parent->type) & type_mask))
+ return NULL;
+
+ if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
+ if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
+ node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+ *id_out = map[index].output_base;
+ return parent;
+ }
+ }
+
+ return NULL;
+}
+
static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node,
u32 rid_in, u32 *rid_out,
- u8 type)
+ u8 type_mask)
{
u32 rid = rid_in;
@@ -223,7 +370,7 @@ static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node,
struct acpi_iort_id_mapping *map;
int i;
- if (node->type == type) {
+ if (IORT_TYPE_MASK(node->type) & type_mask) {
if (rid_out)
*rid_out = rid;
return node;
@@ -296,7 +443,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
if (!node)
return req_id;
- iort_node_map_rid(node, req_id, &dev_id, ACPI_IORT_NODE_ITS_GROUP);
+ iort_node_map_rid(node, req_id, &dev_id, IORT_MSI_TYPE);
return dev_id;
}
@@ -318,7 +465,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
if (!node)
return -ENXIO;
- node = iort_node_map_rid(node, req_id, NULL, ACPI_IORT_NODE_ITS_GROUP);
+ node = iort_node_map_rid(node, req_id, NULL, IORT_MSI_TYPE);
if (!node)
return -ENXIO;
@@ -356,13 +503,459 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
}
+static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
+{
+ u32 *rid = data;
+
+ *rid = alias;
+ return 0;
+}
+
+static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+ struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops)
+{
+ int ret = iommu_fwspec_init(dev, fwnode, ops);
+
+ if (!ret)
+ ret = iommu_fwspec_add_ids(dev, &streamid, 1);
+
+ return ret;
+}
+
+static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
+ struct acpi_iort_node *node,
+ u32 streamid)
+{
+ const struct iommu_ops *ops = NULL;
+ int ret = -ENODEV;
+ struct fwnode_handle *iort_fwnode;
+
+ if (node) {
+ iort_fwnode = iort_get_fwnode(node);
+ if (!iort_fwnode)
+ return NULL;
+
+ ops = iommu_get_instance(iort_fwnode);
+ if (!ops)
+ return NULL;
+
+ ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
+ }
+
+ return ret ? NULL : ops;
+}
+
+/**
+ * iort_set_dma_mask - Set-up dma mask for a device.
+ *
+ * @dev: device to configure
+ */
+void iort_set_dma_mask(struct device *dev)
+{
+ /*
+ * Set default coherent_dma_mask to 32 bit. Drivers are expected to
+ * setup the correct supported mask.
+ */
+ if (!dev->coherent_dma_mask)
+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ /*
+ * Set it to coherent_dma_mask by default if the architecture
+ * code has not set it.
+ */
+ if (!dev->dma_mask)
+ dev->dma_mask = &dev->coherent_dma_mask;
+}
+
+/**
+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ *
+ * @dev: device to configure
+ *
+ * Returns: iommu_ops pointer on configuration success
+ * NULL on configuration failure
+ */
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{
+ struct acpi_iort_node *node, *parent;
+ const struct iommu_ops *ops = NULL;
+ u32 streamid = 0;
+
+ if (dev_is_pci(dev)) {
+ struct pci_bus *bus = to_pci_dev(dev)->bus;
+ u32 rid;
+
+ pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
+ &rid);
+
+ node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+ iort_match_node_callback, &bus->dev);
+ if (!node)
+ return NULL;
+
+ parent = iort_node_map_rid(node, rid, &streamid,
+ IORT_IOMMU_TYPE);
+
+ ops = iort_iommu_xlate(dev, parent, streamid);
+
+ } else {
+ int i = 0;
+
+ node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_match_node_callback, dev);
+ if (!node)
+ return NULL;
+
+ parent = iort_node_get_id(node, &streamid,
+ IORT_IOMMU_TYPE, i++);
+
+ while (parent) {
+ ops = iort_iommu_xlate(dev, parent, streamid);
+
+ parent = iort_node_get_id(node, &streamid,
+ IORT_IOMMU_TYPE, i++);
+ }
+ }
+
+ return ops;
+}
+
+static void __init acpi_iort_register_irq(int hwirq, const char *name,
+ int trigger,
+ struct resource *res)
+{
+ int irq = acpi_register_gsi(NULL, hwirq, trigger,
+ ACPI_ACTIVE_HIGH);
+
+ if (irq <= 0) {
+ pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
+ name);
+ return;
+ }
+
+ res->start = irq;
+ res->end = irq;
+ res->flags = IORESOURCE_IRQ;
+ res->name = name;
+}
+
+static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+ /* Always present mem resource */
+ int num_res = 1;
+
+ /* Retrieve SMMUv3 specific data */
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ if (smmu->event_gsiv)
+ num_res++;
+
+ if (smmu->pri_gsiv)
+ num_res++;
+
+ if (smmu->gerr_gsiv)
+ num_res++;
+
+ if (smmu->sync_gsiv)
+ num_res++;
+
+ return num_res;
+}
+
+static void __init arm_smmu_v3_init_resources(struct resource *res,
+ struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+ int num_res = 0;
+
+ /* Retrieve SMMUv3 specific data */
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ res[num_res].start = smmu->base_address;
+ res[num_res].end = smmu->base_address + SZ_128K - 1;
+ res[num_res].flags = IORESOURCE_MEM;
+
+ num_res++;
+
+ if (smmu->event_gsiv)
+ acpi_iort_register_irq(smmu->event_gsiv, "eventq",
+ ACPI_EDGE_SENSITIVE,
+ &res[num_res++]);
+
+ if (smmu->pri_gsiv)
+ acpi_iort_register_irq(smmu->pri_gsiv, "priq",
+ ACPI_EDGE_SENSITIVE,
+ &res[num_res++]);
+
+ if (smmu->gerr_gsiv)
+ acpi_iort_register_irq(smmu->gerr_gsiv, "gerror",
+ ACPI_EDGE_SENSITIVE,
+ &res[num_res++]);
+
+ if (smmu->sync_gsiv)
+ acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync",
+ ACPI_EDGE_SENSITIVE,
+ &res[num_res++]);
+}
+
+static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu_v3 *smmu;
+
+ /* Retrieve SMMUv3 specific data */
+ smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
+}
+
+static int __init arm_smmu_count_resources(struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu *smmu;
+
+ /* Retrieve SMMU specific data */
+ smmu = (struct acpi_iort_smmu *)node->node_data;
+
+ /*
+ * Only consider the global fault interrupt and ignore the
+ * configuration access interrupt.
+ *
+ * MMIO address and global fault interrupt resources are always
+ * present so add them to the context interrupt count as a static
+ * value.
+ */
+ return smmu->context_interrupt_count + 2;
+}
+
+static void __init arm_smmu_init_resources(struct resource *res,
+ struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu *smmu;
+ int i, hw_irq, trigger, num_res = 0;
+ u64 *ctx_irq, *glb_irq;
+
+ /* Retrieve SMMU specific data */
+ smmu = (struct acpi_iort_smmu *)node->node_data;
+
+ res[num_res].start = smmu->base_address;
+ res[num_res].end = smmu->base_address + smmu->span - 1;
+ res[num_res].flags = IORESOURCE_MEM;
+ num_res++;
+
+ glb_irq = ACPI_ADD_PTR(u64, node, smmu->global_interrupt_offset);
+ /* Global IRQs */
+ hw_irq = IORT_IRQ_MASK(glb_irq[0]);
+ trigger = IORT_IRQ_TRIGGER_MASK(glb_irq[0]);
+
+ acpi_iort_register_irq(hw_irq, "arm-smmu-global", trigger,
+ &res[num_res++]);
+
+ /* Context IRQs */
+ ctx_irq = ACPI_ADD_PTR(u64, node, smmu->context_interrupt_offset);
+ for (i = 0; i < smmu->context_interrupt_count; i++) {
+ hw_irq = IORT_IRQ_MASK(ctx_irq[i]);
+ trigger = IORT_IRQ_TRIGGER_MASK(ctx_irq[i]);
+
+ acpi_iort_register_irq(hw_irq, "arm-smmu-context", trigger,
+ &res[num_res++]);
+ }
+}
+
+static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node)
+{
+ struct acpi_iort_smmu *smmu;
+
+ /* Retrieve SMMU specific data */
+ smmu = (struct acpi_iort_smmu *)node->node_data;
+
+ return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK;
+}
+
+struct iort_iommu_config {
+ const char *name;
+ int (*iommu_init)(struct acpi_iort_node *node);
+ bool (*iommu_is_coherent)(struct acpi_iort_node *node);
+ int (*iommu_count_resources)(struct acpi_iort_node *node);
+ void (*iommu_init_resources)(struct resource *res,
+ struct acpi_iort_node *node);
+};
+
+static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = {
+ .name = "arm-smmu-v3",
+ .iommu_is_coherent = arm_smmu_v3_is_coherent,
+ .iommu_count_resources = arm_smmu_v3_count_resources,
+ .iommu_init_resources = arm_smmu_v3_init_resources
+};
+
+static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = {
+ .name = "arm-smmu",
+ .iommu_is_coherent = arm_smmu_is_coherent,
+ .iommu_count_resources = arm_smmu_count_resources,
+ .iommu_init_resources = arm_smmu_init_resources
+};
+
+static __init
+const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node)
+{
+ switch (node->type) {
+ case ACPI_IORT_NODE_SMMU_V3:
+ return &iort_arm_smmu_v3_cfg;
+ case ACPI_IORT_NODE_SMMU:
+ return &iort_arm_smmu_cfg;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * iort_add_smmu_platform_device() - Allocate a platform device for SMMU
+ * @node: Pointer to SMMU ACPI IORT node
+ *
+ * Returns: 0 on success, <0 failure
+ */
+static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
+{
+ struct fwnode_handle *fwnode;
+ struct platform_device *pdev;
+ struct resource *r;
+ enum dev_dma_attr attr;
+ int ret, count;
+ const struct iort_iommu_config *ops = iort_get_iommu_cfg(node);
+
+ if (!ops)
+ return -ENODEV;
+
+ pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
+ if (!pdev)
+ return PTR_ERR(pdev);
+
+ count = ops->iommu_count_resources(node);
+
+ r = kcalloc(count, sizeof(*r), GFP_KERNEL);
+ if (!r) {
+ ret = -ENOMEM;
+ goto dev_put;
+ }
+
+ ops->iommu_init_resources(r, node);
+
+ ret = platform_device_add_resources(pdev, r, count);
+ /*
+ * Resources are duplicated in platform_device_add_resources,
+ * free their allocated memory
+ */
+ kfree(r);
+
+ if (ret)
+ goto dev_put;
+
+ /*
+ * Add a copy of IORT node pointer to platform_data to
+ * be used to retrieve IORT data information.
+ */
+ ret = platform_device_add_data(pdev, &node, sizeof(node));
+ if (ret)
+ goto dev_put;
+
+ /*
+ * We expect the dma masks to be equivalent for
+ * all SMMUs set-ups
+ */
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+ fwnode = iort_get_fwnode(node);
+
+ if (!fwnode) {
+ ret = -ENODEV;
+ goto dev_put;
+ }
+
+ pdev->dev.fwnode = fwnode;
+
+ attr = ops->iommu_is_coherent(node) ?
+ DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
+
+ /* Configure DMA for the page table walker */
+ acpi_dma_configure(&pdev->dev, attr);
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto dma_deconfigure;
+
+ return 0;
+
+dma_deconfigure:
+ acpi_dma_deconfigure(&pdev->dev);
+dev_put:
+ platform_device_put(pdev);
+
+ return ret;
+}
+
+static void __init iort_init_platform_devices(void)
+{
+ struct acpi_iort_node *iort_node, *iort_end;
+ struct acpi_table_iort *iort;
+ struct fwnode_handle *fwnode;
+ int i, ret;
+
+ /*
+ * iort_table and iort both point to the start of IORT table, but
+ * have different struct types
+ */
+ iort = (struct acpi_table_iort *)iort_table;
+
+ /* Get the first IORT node */
+ iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+ iort->node_offset);
+ iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+ iort_table->length);
+
+ for (i = 0; i < iort->node_count; i++) {
+ if (iort_node >= iort_end) {
+ pr_err("iort node pointer overflows, bad table\n");
+ return;
+ }
+
+ if ((iort_node->type == ACPI_IORT_NODE_SMMU) ||
+ (iort_node->type == ACPI_IORT_NODE_SMMU_V3)) {
+
+ fwnode = acpi_alloc_fwnode_static();
+ if (!fwnode)
+ return;
+
+ iort_set_fwnode(iort_node, fwnode);
+
+ ret = iort_add_smmu_platform_device(iort_node);
+ if (ret) {
+ iort_delete_fwnode(iort_node);
+ acpi_free_fwnode_static(fwnode);
+ return;
+ }
+ }
+
+ iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+ iort_node->length);
+ }
+}
+
void __init acpi_iort_init(void)
{
acpi_status status;
status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
- const char *msg = acpi_format_exception(status);
- pr_err("Failed to get table, %s\n", msg);
+ if (ACPI_FAILURE(status)) {
+ if (status != AE_NOT_FOUND) {
+ const char *msg = acpi_format_exception(status);
+
+ pr_err("Failed to get table, %s\n", msg);
+ }
+
+ return;
}
+
+ iort_init_platform_devices();
+
+ acpi_probe_device_table(iort);
}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5ea5dc219f56..f8d65647ea79 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -227,8 +227,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
attr = acpi_get_dma_attr(acpi_dev);
if (attr != DEV_DMA_NOT_SUPPORTED)
- arch_setup_dma_ops(dev, 0, 0, NULL,
- attr == DEV_DMA_COHERENT);
+ acpi_dma_configure(dev, attr);
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
@@ -251,6 +250,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
return 0;
err:
+ acpi_dma_deconfigure(dev);
ACPI_COMPANION_SET(dev, NULL);
put_device(dev);
put_device(&acpi_dev->dev);
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
index b5b376e081f5..a6a4ceaa6cc3 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
+#include <linux/pci-ecam.h>
/* Structure to hold entries from the MCFG table */
struct mcfg_entry {
@@ -32,12 +33,166 @@ struct mcfg_entry {
u8 bus_end;
};
+#ifdef CONFIG_PCI_QUIRKS
+struct mcfg_fixup {
+ char oem_id[ACPI_OEM_ID_SIZE + 1];
+ char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+ u32 oem_revision;
+ u16 segment;
+ struct resource bus_range;
+ struct pci_ecam_ops *ops;
+ struct resource cfgres;
+};
+
+#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \
+ ((end) - (start) + 1), \
+ NULL, IORESOURCE_BUS)
+#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
+
+static struct mcfg_fixup mcfg_quirks[] = {
+/* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */
+
+#define QCOM_ECAM32(seg) \
+ { "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops }
+ QCOM_ECAM32(0),
+ QCOM_ECAM32(1),
+ QCOM_ECAM32(2),
+ QCOM_ECAM32(3),
+ QCOM_ECAM32(4),
+ QCOM_ECAM32(5),
+ QCOM_ECAM32(6),
+ QCOM_ECAM32(7),
+
+#define HISI_QUAD_DOM(table_id, seg, ops) \
+ { "HISI ", table_id, 0, (seg) + 0, MCFG_BUS_ANY, ops }, \
+ { "HISI ", table_id, 0, (seg) + 1, MCFG_BUS_ANY, ops }, \
+ { "HISI ", table_id, 0, (seg) + 2, MCFG_BUS_ANY, ops }, \
+ { "HISI ", table_id, 0, (seg) + 3, MCFG_BUS_ANY, ops }
+ HISI_QUAD_DOM("HIP05 ", 0, &hisi_pcie_ops),
+ HISI_QUAD_DOM("HIP06 ", 0, &hisi_pcie_ops),
+ HISI_QUAD_DOM("HIP07 ", 0, &hisi_pcie_ops),
+ HISI_QUAD_DOM("HIP07 ", 4, &hisi_pcie_ops),
+ HISI_QUAD_DOM("HIP07 ", 8, &hisi_pcie_ops),
+ HISI_QUAD_DOM("HIP07 ", 12, &hisi_pcie_ops),
+
+#define THUNDER_PEM_RES(addr, node) \
+ DEFINE_RES_MEM((addr) + ((u64) (node) << 44), 0x39 * SZ_16M)
+#define THUNDER_PEM_QUIRK(rev, node) \
+ { "CAVIUM", "THUNDERX", rev, 4 + (10 * (node)), MCFG_BUS_ANY, \
+ &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88001f000000UL, node) }, \
+ { "CAVIUM", "THUNDERX", rev, 5 + (10 * (node)), MCFG_BUS_ANY, \
+ &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x884057000000UL, node) }, \
+ { "CAVIUM", "THUNDERX", rev, 6 + (10 * (node)), MCFG_BUS_ANY, \
+ &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88808f000000UL, node) }, \
+ { "CAVIUM", "THUNDERX", rev, 7 + (10 * (node)), MCFG_BUS_ANY, \
+ &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89001f000000UL, node) }, \
+ { "CAVIUM", "THUNDERX", rev, 8 + (10 * (node)), MCFG_BUS_ANY, \
+ &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x894057000000UL, node) }, \
+ { "CAVIUM", "THUNDERX", rev, 9 + (10 * (node)), MCFG_BUS_ANY, \
+ &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89808f000000UL, node) }
+ /* SoC pass2.x */
+ THUNDER_PEM_QUIRK(1, 0),
+ THUNDER_PEM_QUIRK(1, 1),
+
+#define THUNDER_ECAM_QUIRK(rev, seg) \
+ { "CAVIUM", "THUNDERX", rev, seg, MCFG_BUS_ANY, \
+ &pci_thunder_ecam_ops }
+ /* SoC pass1.x */
+ THUNDER_PEM_QUIRK(2, 0), /* off-chip devices */
+ THUNDER_PEM_QUIRK(2, 1), /* off-chip devices */
+ THUNDER_ECAM_QUIRK(2, 0),
+ THUNDER_ECAM_QUIRK(2, 1),
+ THUNDER_ECAM_QUIRK(2, 2),
+ THUNDER_ECAM_QUIRK(2, 3),
+ THUNDER_ECAM_QUIRK(2, 10),
+ THUNDER_ECAM_QUIRK(2, 11),
+ THUNDER_ECAM_QUIRK(2, 12),
+ THUNDER_ECAM_QUIRK(2, 13),
+
+#define XGENE_V1_ECAM_MCFG(rev, seg) \
+ {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
+ &xgene_v1_pcie_ecam_ops }
+#define XGENE_V2_ECAM_MCFG(rev, seg) \
+ {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
+ &xgene_v2_pcie_ecam_ops }
+ /* X-Gene SoC with v1 PCIe controller */
+ XGENE_V1_ECAM_MCFG(1, 0),
+ XGENE_V1_ECAM_MCFG(1, 1),
+ XGENE_V1_ECAM_MCFG(1, 2),
+ XGENE_V1_ECAM_MCFG(1, 3),
+ XGENE_V1_ECAM_MCFG(1, 4),
+ XGENE_V1_ECAM_MCFG(2, 0),
+ XGENE_V1_ECAM_MCFG(2, 1),
+ XGENE_V1_ECAM_MCFG(2, 2),
+ XGENE_V1_ECAM_MCFG(2, 3),
+ XGENE_V1_ECAM_MCFG(2, 4),
+ /* X-Gene SoC with v2.1 PCIe controller */
+ XGENE_V2_ECAM_MCFG(3, 0),
+ XGENE_V2_ECAM_MCFG(3, 1),
+ /* X-Gene SoC with v2.2 PCIe controller */
+ XGENE_V2_ECAM_MCFG(4, 0),
+ XGENE_V2_ECAM_MCFG(4, 1),
+ XGENE_V2_ECAM_MCFG(4, 2),
+};
+
+static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
+static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
+static u32 mcfg_oem_revision;
+
+static int pci_mcfg_quirk_matches(struct mcfg_fixup *f, u16 segment,
+ struct resource *bus_range)
+{
+ if (!memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) &&
+ !memcmp(f->oem_table_id, mcfg_oem_table_id,
+ ACPI_OEM_TABLE_ID_SIZE) &&
+ f->oem_revision == mcfg_oem_revision &&
+ f->segment == segment &&
+ resource_contains(&f->bus_range, bus_range))
+ return 1;
+
+ return 0;
+}
+#endif
+
+static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
+ struct resource *cfgres,
+ struct pci_ecam_ops **ecam_ops)
+{
+#ifdef CONFIG_PCI_QUIRKS
+ u16 segment = root->segment;
+ struct resource *bus_range = &root->secondary;
+ struct mcfg_fixup *f;
+ int i;
+
+ for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
+ if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
+ if (f->cfgres.start)
+ *cfgres = f->cfgres;
+ if (f->ops)
+ *ecam_ops = f->ops;
+ dev_info(&root->device->dev, "MCFG quirk: ECAM at %pR for %pR with %ps\n",
+ cfgres, bus_range, *ecam_ops);
+ return;
+ }
+ }
+#endif
+}
+
/* List to save MCFG entries */
static LIST_HEAD(pci_mcfg_list);
-phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
+int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
+ struct pci_ecam_ops **ecam_ops)
{
+ struct pci_ecam_ops *ops = &pci_generic_ecam_ops;
+ struct resource *bus_res = &root->secondary;
+ u16 seg = root->segment;
struct mcfg_entry *e;
+ struct resource res;
+
+ /* Use address from _CBA if present, otherwise lookup MCFG */
+ if (root->mcfg_addr)
+ goto skip_lookup;
/*
* We expect exact match, unless MCFG entry end bus covers more than
@@ -45,10 +200,32 @@ phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
*/
list_for_each_entry(e, &pci_mcfg_list, list) {
if (e->segment == seg && e->bus_start == bus_res->start &&
- e->bus_end >= bus_res->end)
- return e->addr;
+ e->bus_end >= bus_res->end) {
+ root->mcfg_addr = e->addr;
+ }
+
+ }
+
+skip_lookup:
+ memset(&res, 0, sizeof(res));
+ if (root->mcfg_addr) {
+ res.start = root->mcfg_addr + (bus_res->start << 20);
+ res.end = res.start + (resource_size(bus_res) << 20) - 1;
+ res.flags = IORESOURCE_MEM;
}
+ /*
+ * Allow quirks to override default ECAM ops and CFG resource
+ * range. This may even fabricate a CFG resource range in case
+ * MCFG does not have it. Invalid CFG start address means MCFG
+ * firmware bug or we need another quirk in array.
+ */
+ pci_mcfg_apply_quirks(root, &res, &ops);
+ if (!res.start)
+ return -ENXIO;
+
+ *cfgres = res;
+ *ecam_ops = ops;
return 0;
}
@@ -79,6 +256,13 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header)
list_add(&e->list, &pci_mcfg_list);
}
+#ifdef CONFIG_PCI_QUIRKS
+ /* Save MCFG IDs and revision for quirks matching */
+ memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE);
+ memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
+ mcfg_oem_revision = header->oem_revision;
+#endif
+
pr_info("MCFG table detected, %d entries\n", n);
return 0;
}
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 56241eb341f4..cb57962ef7c4 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -664,3 +664,60 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,
return (type & types) ? 0 : 1;
}
EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
+
+static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res)
+{
+ struct list_head resource_list;
+ struct resource_entry *rentry;
+ int ret, found = 0;
+
+ INIT_LIST_HEAD(&resource_list);
+ ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+ if (ret < 0)
+ return 0;
+
+ list_for_each_entry(rentry, &resource_list, node) {
+ if (resource_contains(rentry->res, res)) {
+ found = 1;
+ break;
+ }
+
+ }
+
+ acpi_dev_free_resource_list(&resource_list);
+ return found;
+}
+
+static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth,
+ void *context, void **ret)
+{
+ struct resource *res = context;
+ struct acpi_device **consumer = (struct acpi_device **) ret;
+ struct acpi_device *adev;
+
+ if (acpi_bus_get_device(handle, &adev))
+ return AE_OK;
+
+ if (acpi_dev_consumes_res(adev, res)) {
+ *consumer = adev;
+ return AE_CTRL_TERMINATE;
+ }
+
+ return AE_OK;
+}
+
+/**
+ * acpi_resource_consumer - Find the ACPI device that consumes @res.
+ * @res: Resource to search for.
+ *
+ * Search the current resource settings (_CRS) of every ACPI device node
+ * for @res. If we find an ACPI device whose _CRS includes @res, return
+ * it. Otherwise, return NULL.
+ */
+struct acpi_device *acpi_resource_consumer(struct resource *res)
+{
+ struct acpi_device *consumer = NULL;
+
+ acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer);
+ return consumer;
+}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3d1856f1f4d0..93b00cf4eb39 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/signal.h>
#include <linux/kthread.h>
#include <linux/dmi.h>
@@ -1370,6 +1371,38 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
return DEV_DMA_NON_COHERENT;
}
+/**
+ * acpi_dma_configure - Set-up DMA configuration for the device.
+ * @dev: The pointer to the device
+ * @attr: device dma attributes
+ */
+void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+{
+ const struct iommu_ops *iommu;
+
+ iort_set_dma_mask(dev);
+
+ iommu = iort_iommu_configure(dev);
+
+ /*
+ * Assume dma valid range starts at 0 and covers the whole
+ * coherent_dma_mask.
+ */
+ arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
+ attr == DEV_DMA_COHERENT);
+}
+EXPORT_SYMBOL_GPL(acpi_dma_configure);
+
+/**
+ * acpi_dma_deconfigure - Tear-down DMA configuration for the device.
+ * @dev: The pointer to the device
+ */
+void acpi_dma_deconfigure(struct device *dev)
+{
+ arch_teardown_dma_ops(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_dma_deconfigure);
+
static void acpi_init_coherency(struct acpi_device *adev)
{
unsigned long long cca = 0;
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 78751057164a..b9e8cfc93c7e 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -150,6 +150,13 @@ config TEGRA_ACONNECT
Driver for the Tegra ACONNECT bus which is used to interface with
the devices inside the Audio Processing Engine (APE) for Tegra210.
+config TEGRA_GMI
+ tristate "Tegra Generic Memory Interface bus driver"
+ depends on ARCH_TEGRA
+ help
+ Driver for the Tegra Generic Memory Interface bus which can be used
+ to attach devices such as NOR, UART, FPGA and more.
+
config UNIPHIER_SYSTEM_BUS
tristate "UniPhier System Bus driver"
depends on ARCH_UNIPHIER && OF
@@ -167,4 +174,13 @@ config VEXPRESS_CONFIG
help
Platform configuration infrastructure for the ARM Ltd.
Versatile Express.
+
+config DA8XX_MSTPRI
+ bool "TI da8xx master peripheral priority driver"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Driver for Texas Instruments da8xx master peripheral priority
+ configuration. Allows to adjust the priorities of all master
+ peripherals.
+
endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index c6cfa6b2606e..cc6364bec054 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -19,5 +19,8 @@ obj-$(CONFIG_QCOM_EBI2) += qcom-ebi2.o
obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o
obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_TEGRA_ACONNECT) += tegra-aconnect.o
+obj-$(CONFIG_TEGRA_GMI) += tegra-gmi.o
obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
+
+obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 890082315054..231633328dfa 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -2190,6 +2190,9 @@ static int cci_probe_ports(struct device_node *np)
if (!of_match_node(arm_cci_ctrl_if_matches, cp))
continue;
+ if (!of_device_is_available(cp))
+ continue;
+
i = nb_ace + nb_ace_lite;
if (i >= nb_cci_ports)
@@ -2232,6 +2235,13 @@ static int cci_probe_ports(struct device_node *np)
ports[i].dn = cp;
}
+ /*
+ * If there is no CCI port that is under kernel control
+ * return early and report probe status.
+ */
+ if (!nb_ace && !nb_ace_lite)
+ return -ENODEV;
+
/* initialize a stashed array of ACE ports to speed-up look-up */
cci_ace_init_ports();
diff --git a/drivers/bus/da8xx-mstpri.c b/drivers/bus/da8xx-mstpri.c
new file mode 100644
index 000000000000..063397f2c0db
--- /dev/null
+++ b/drivers/bus/da8xx-mstpri.c
@@ -0,0 +1,267 @@
+/*
+ * TI da8xx master peripheral priority driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com.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/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+#define DA8XX_MSTPRI0_OFFSET 0
+#define DA8XX_MSTPRI1_OFFSET 4
+#define DA8XX_MSTPRI2_OFFSET 8
+
+enum {
+ DA8XX_MSTPRI_ARM_I = 0,
+ DA8XX_MSTPRI_ARM_D,
+ DA8XX_MSTPRI_UPP,
+ DA8XX_MSTPRI_SATA,
+ DA8XX_MSTPRI_PRU0,
+ DA8XX_MSTPRI_PRU1,
+ DA8XX_MSTPRI_EDMA30TC0,
+ DA8XX_MSTPRI_EDMA30TC1,
+ DA8XX_MSTPRI_EDMA31TC0,
+ DA8XX_MSTPRI_VPIF_DMA_0,
+ DA8XX_MSTPRI_VPIF_DMA_1,
+ DA8XX_MSTPRI_EMAC,
+ DA8XX_MSTPRI_USB0CFG,
+ DA8XX_MSTPRI_USB0CDMA,
+ DA8XX_MSTPRI_UHPI,
+ DA8XX_MSTPRI_USB1,
+ DA8XX_MSTPRI_LCDC,
+};
+
+struct da8xx_mstpri_descr {
+ int reg;
+ int shift;
+ int mask;
+};
+
+static const struct da8xx_mstpri_descr da8xx_mstpri_priority_list[] = {
+ [DA8XX_MSTPRI_ARM_I] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_ARM_D] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 4,
+ .mask = 0x000000f0,
+ },
+ [DA8XX_MSTPRI_UPP] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 16,
+ .mask = 0x000f0000,
+ },
+ [DA8XX_MSTPRI_SATA] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 20,
+ .mask = 0x00f00000,
+ },
+ [DA8XX_MSTPRI_PRU0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_PRU1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 4,
+ .mask = 0x000000f0,
+ },
+ [DA8XX_MSTPRI_EDMA30TC0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 8,
+ .mask = 0x00000f00,
+ },
+ [DA8XX_MSTPRI_EDMA30TC1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 12,
+ .mask = 0x0000f000,
+ },
+ [DA8XX_MSTPRI_EDMA31TC0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 16,
+ .mask = 0x000f0000,
+ },
+ [DA8XX_MSTPRI_VPIF_DMA_0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 24,
+ .mask = 0x0f000000,
+ },
+ [DA8XX_MSTPRI_VPIF_DMA_1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 28,
+ .mask = 0xf0000000,
+ },
+ [DA8XX_MSTPRI_EMAC] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_USB0CFG] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 8,
+ .mask = 0x00000f00,
+ },
+ [DA8XX_MSTPRI_USB0CDMA] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 12,
+ .mask = 0x0000f000,
+ },
+ [DA8XX_MSTPRI_UHPI] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 20,
+ .mask = 0x00f00000,
+ },
+ [DA8XX_MSTPRI_USB1] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 24,
+ .mask = 0x0f000000,
+ },
+ [DA8XX_MSTPRI_LCDC] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 28,
+ .mask = 0xf0000000,
+ },
+};
+
+struct da8xx_mstpri_priority {
+ int which;
+ u32 val;
+};
+
+struct da8xx_mstpri_board_priorities {
+ const char *board;
+ const struct da8xx_mstpri_priority *priorities;
+ size_t numprio;
+};
+
+/*
+ * Default memory settings of da850 do not meet the throughput/latency
+ * requirements of tilcdc. This results in the image displayed being
+ * incorrect and the following warning being displayed by the LCDC
+ * drm driver:
+ *
+ * tilcdc da8xx_lcdc.0: tilcdc_crtc_irq(0x00000020): FIFO underfow
+ */
+static const struct da8xx_mstpri_priority da850_lcdk_priorities[] = {
+ {
+ .which = DA8XX_MSTPRI_LCDC,
+ .val = 0,
+ },
+ {
+ .which = DA8XX_MSTPRI_EDMA30TC1,
+ .val = 0,
+ },
+ {
+ .which = DA8XX_MSTPRI_EDMA30TC0,
+ .val = 1,
+ },
+};
+
+static const struct da8xx_mstpri_board_priorities da8xx_mstpri_board_confs[] = {
+ {
+ .board = "ti,da850-lcdk",
+ .priorities = da850_lcdk_priorities,
+ .numprio = ARRAY_SIZE(da850_lcdk_priorities),
+ },
+};
+
+static const struct da8xx_mstpri_board_priorities *
+da8xx_mstpri_get_board_prio(void)
+{
+ const struct da8xx_mstpri_board_priorities *board_prio;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_mstpri_board_confs); i++) {
+ board_prio = &da8xx_mstpri_board_confs[i];
+
+ if (of_machine_is_compatible(board_prio->board))
+ return board_prio;
+ }
+
+ return NULL;
+}
+
+static int da8xx_mstpri_probe(struct platform_device *pdev)
+{
+ const struct da8xx_mstpri_board_priorities *prio_list;
+ const struct da8xx_mstpri_descr *prio_descr;
+ const struct da8xx_mstpri_priority *prio;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *mstpri;
+ u32 reg;
+ int i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mstpri = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mstpri)) {
+ dev_err(dev, "unable to map MSTPRI registers\n");
+ return PTR_ERR(mstpri);
+ }
+
+ prio_list = da8xx_mstpri_get_board_prio();
+ if (!prio_list) {
+ dev_err(dev, "no master priorities defined for this board\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < prio_list->numprio; i++) {
+ prio = &prio_list->priorities[i];
+ prio_descr = &da8xx_mstpri_priority_list[prio->which];
+
+ if (prio_descr->reg + sizeof(u32) > resource_size(res)) {
+ dev_warn(dev, "register offset out of range\n");
+ continue;
+ }
+
+ reg = readl(mstpri + prio_descr->reg);
+ reg &= ~prio_descr->mask;
+ reg |= prio->val << prio_descr->shift;
+
+ writel(reg, mstpri + prio_descr->reg);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id da8xx_mstpri_of_match[] = {
+ { .compatible = "ti,da850-mstpri", },
+ { },
+};
+
+static struct platform_driver da8xx_mstpri_driver = {
+ .probe = da8xx_mstpri_probe,
+ .driver = {
+ .name = "da8xx-mstpri",
+ .of_match_table = da8xx_mstpri_of_match,
+ },
+};
+module_platform_driver(da8xx_mstpri_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx master peripheral priority driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c
new file mode 100644
index 000000000000..a6570789f7af
--- /dev/null
+++ b/drivers/bus/tegra-gmi.c
@@ -0,0 +1,284 @@
+/*
+ * Driver for NVIDIA Generic Memory Interface
+ *
+ * Copyright (C) 2016 Host Mobility AB. All rights reserved.
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+
+#define TEGRA_GMI_CONFIG 0x00
+#define TEGRA_GMI_CONFIG_GO BIT(31)
+#define TEGRA_GMI_BUS_WIDTH_32BIT BIT(30)
+#define TEGRA_GMI_MUX_MODE BIT(28)
+#define TEGRA_GMI_RDY_BEFORE_DATA BIT(24)
+#define TEGRA_GMI_RDY_ACTIVE_HIGH BIT(23)
+#define TEGRA_GMI_ADV_ACTIVE_HIGH BIT(22)
+#define TEGRA_GMI_OE_ACTIVE_HIGH BIT(21)
+#define TEGRA_GMI_CS_ACTIVE_HIGH BIT(20)
+#define TEGRA_GMI_CS_SELECT(x) ((x & 0x7) << 4)
+
+#define TEGRA_GMI_TIMING0 0x10
+#define TEGRA_GMI_MUXED_WIDTH(x) ((x & 0xf) << 12)
+#define TEGRA_GMI_HOLD_WIDTH(x) ((x & 0xf) << 8)
+#define TEGRA_GMI_ADV_WIDTH(x) ((x & 0xf) << 4)
+#define TEGRA_GMI_CE_WIDTH(x) (x & 0xf)
+
+#define TEGRA_GMI_TIMING1 0x14
+#define TEGRA_GMI_WE_WIDTH(x) ((x & 0xff) << 16)
+#define TEGRA_GMI_OE_WIDTH(x) ((x & 0xff) << 8)
+#define TEGRA_GMI_WAIT_WIDTH(x) (x & 0xff)
+
+#define TEGRA_GMI_MAX_CHIP_SELECT 8
+
+struct tegra_gmi {
+ struct device *dev;
+ void __iomem *base;
+ struct clk *clk;
+ struct reset_control *rst;
+
+ u32 snor_config;
+ u32 snor_timing0;
+ u32 snor_timing1;
+};
+
+static int tegra_gmi_enable(struct tegra_gmi *gmi)
+{
+ int err;
+
+ err = clk_prepare_enable(gmi->clk);
+ if (err < 0) {
+ dev_err(gmi->dev, "failed to enable clock: %d\n", err);
+ return err;
+ }
+
+ reset_control_assert(gmi->rst);
+ usleep_range(2000, 4000);
+ reset_control_deassert(gmi->rst);
+
+ writel(gmi->snor_timing0, gmi->base + TEGRA_GMI_TIMING0);
+ writel(gmi->snor_timing1, gmi->base + TEGRA_GMI_TIMING1);
+
+ gmi->snor_config |= TEGRA_GMI_CONFIG_GO;
+ writel(gmi->snor_config, gmi->base + TEGRA_GMI_CONFIG);
+
+ return 0;
+}
+
+static void tegra_gmi_disable(struct tegra_gmi *gmi)
+{
+ u32 config;
+
+ /* stop GMI operation */
+ config = readl(gmi->base + TEGRA_GMI_CONFIG);
+ config &= ~TEGRA_GMI_CONFIG_GO;
+ writel(config, gmi->base + TEGRA_GMI_CONFIG);
+
+ reset_control_assert(gmi->rst);
+ clk_disable_unprepare(gmi->clk);
+}
+
+static int tegra_gmi_parse_dt(struct tegra_gmi *gmi)
+{
+ struct device_node *child;
+ u32 property, ranges[4];
+ int err;
+
+ child = of_get_next_available_child(gmi->dev->of_node, NULL);
+ if (!child) {
+ dev_err(gmi->dev, "no child nodes found\n");
+ return -ENODEV;
+ }
+
+ /*
+ * We currently only support one child device due to lack of
+ * chip-select address decoding. Which means that we only have one
+ * chip-select line from the GMI controller.
+ */
+ if (of_get_child_count(gmi->dev->of_node) > 1)
+ dev_warn(gmi->dev, "only one child device is supported.");
+
+ if (of_property_read_bool(child, "nvidia,snor-data-width-32bit"))
+ gmi->snor_config |= TEGRA_GMI_BUS_WIDTH_32BIT;
+
+ if (of_property_read_bool(child, "nvidia,snor-mux-mode"))
+ gmi->snor_config |= TEGRA_GMI_MUX_MODE;
+
+ if (of_property_read_bool(child, "nvidia,snor-rdy-active-before-data"))
+ gmi->snor_config |= TEGRA_GMI_RDY_BEFORE_DATA;
+
+ if (of_property_read_bool(child, "nvidia,snor-rdy-active-high"))
+ gmi->snor_config |= TEGRA_GMI_RDY_ACTIVE_HIGH;
+
+ if (of_property_read_bool(child, "nvidia,snor-adv-active-high"))
+ gmi->snor_config |= TEGRA_GMI_ADV_ACTIVE_HIGH;
+
+ if (of_property_read_bool(child, "nvidia,snor-oe-active-high"))
+ gmi->snor_config |= TEGRA_GMI_OE_ACTIVE_HIGH;
+
+ if (of_property_read_bool(child, "nvidia,snor-cs-active-high"))
+ gmi->snor_config |= TEGRA_GMI_CS_ACTIVE_HIGH;
+
+ /* Decode the CS# */
+ err = of_property_read_u32_array(child, "ranges", ranges, 4);
+ if (err < 0) {
+ /* Invalid binding */
+ if (err == -EOVERFLOW) {
+ dev_err(gmi->dev,
+ "failed to decode CS: invalid ranges length\n");
+ goto error_cs;
+ }
+
+ /*
+ * If we reach here it means that the child node has an empty
+ * ranges or it does not exist at all. Attempt to decode the
+ * CS# from the reg property instead.
+ */
+ err = of_property_read_u32(child, "reg", &property);
+ if (err < 0) {
+ dev_err(gmi->dev,
+ "failed to decode CS: no reg property found\n");
+ goto error_cs;
+ }
+ } else {
+ property = ranges[1];
+ }
+
+ /* Valid chip selects are CS0-CS7 */
+ if (property >= TEGRA_GMI_MAX_CHIP_SELECT) {
+ dev_err(gmi->dev, "invalid chip select: %d", property);
+ err = -EINVAL;
+ goto error_cs;
+ }
+
+ gmi->snor_config |= TEGRA_GMI_CS_SELECT(property);
+
+ /* The default values that are provided below are reset values */
+ if (!of_property_read_u32(child, "nvidia,snor-muxed-width", &property))
+ gmi->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(property);
+ else
+ gmi->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-hold-width", &property))
+ gmi->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(property);
+ else
+ gmi->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-adv-width", &property))
+ gmi->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(property);
+ else
+ gmi->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-ce-width", &property))
+ gmi->snor_timing0 |= TEGRA_GMI_CE_WIDTH(property);
+ else
+ gmi->snor_timing0 |= TEGRA_GMI_CE_WIDTH(4);
+
+ if (!of_property_read_u32(child, "nvidia,snor-we-width", &property))
+ gmi->snor_timing1 |= TEGRA_GMI_WE_WIDTH(property);
+ else
+ gmi->snor_timing1 |= TEGRA_GMI_WE_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-oe-width", &property))
+ gmi->snor_timing1 |= TEGRA_GMI_OE_WIDTH(property);
+ else
+ gmi->snor_timing1 |= TEGRA_GMI_OE_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-wait-width", &property))
+ gmi->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(property);
+ else
+ gmi->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(3);
+
+error_cs:
+ of_node_put(child);
+ return err;
+}
+
+static int tegra_gmi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct tegra_gmi *gmi;
+ struct resource *res;
+ int err;
+
+ gmi = devm_kzalloc(dev, sizeof(*gmi), GFP_KERNEL);
+ if (!gmi)
+ return -ENOMEM;
+
+ gmi->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ gmi->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(gmi->base))
+ return PTR_ERR(gmi->base);
+
+ gmi->clk = devm_clk_get(dev, "gmi");
+ if (IS_ERR(gmi->clk)) {
+ dev_err(dev, "can not get clock\n");
+ return PTR_ERR(gmi->clk);
+ }
+
+ gmi->rst = devm_reset_control_get(dev, "gmi");
+ if (IS_ERR(gmi->rst)) {
+ dev_err(dev, "can not get reset\n");
+ return PTR_ERR(gmi->rst);
+ }
+
+ err = tegra_gmi_parse_dt(gmi);
+ if (err)
+ return err;
+
+ err = tegra_gmi_enable(gmi);
+ if (err < 0)
+ return err;
+
+ err = of_platform_default_populate(dev->of_node, NULL, dev);
+ if (err < 0) {
+ dev_err(dev, "fail to create devices.\n");
+ tegra_gmi_disable(gmi);
+ return err;
+ }
+
+ platform_set_drvdata(pdev, gmi);
+
+ return 0;
+}
+
+static int tegra_gmi_remove(struct platform_device *pdev)
+{
+ struct tegra_gmi *gmi = platform_get_drvdata(pdev);
+
+ of_platform_depopulate(gmi->dev);
+ tegra_gmi_disable(gmi);
+
+ return 0;
+}
+
+static const struct of_device_id tegra_gmi_id_table[] = {
+ { .compatible = "nvidia,tegra20-gmi", },
+ { .compatible = "nvidia,tegra30-gmi", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tegra_gmi_id_table);
+
+static struct platform_driver tegra_gmi_driver = {
+ .probe = tegra_gmi_probe,
+ .remove = tegra_gmi_remove,
+ .driver = {
+ .name = "tegra-gmi",
+ .of_match_table = tegra_gmi_id_table,
+ },
+};
+module_platform_driver(tegra_gmi_driver);
+
+MODULE_AUTHOR("Mirza Krak <mirza.krak@gmail.com");
+MODULE_DESCRIPTION("NVIDIA Tegra GMI Bus Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/bus/vexpress-config.c b/drivers/bus/vexpress-config.c
index 9efdf1de4035..493e7b9fc813 100644
--- a/drivers/bus/vexpress-config.c
+++ b/drivers/bus/vexpress-config.c
@@ -171,6 +171,7 @@ static int vexpress_config_populate(struct device_node *node)
{
struct device_node *bridge;
struct device *parent;
+ int ret;
bridge = of_parse_phandle(node, "arm,vexpress,config-bridge", 0);
if (!bridge)
@@ -182,7 +183,11 @@ static int vexpress_config_populate(struct device_node *node)
if (WARN_ON(!parent))
return -ENODEV;
- return of_platform_populate(node, NULL, NULL, parent);
+ ret = of_platform_populate(node, NULL, NULL, parent);
+
+ put_device(parent);
+
+ return ret;
}
static int __init vexpress_config_init(void)
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 1786574536b2..a21407de46ae 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -989,4 +989,3 @@ module_exit(cleanup_ipmi);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
-MODULE_ALIAS("platform:ipmi_si");
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index fcdd886819f5..92e53acf2cd2 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -158,15 +158,16 @@ struct seq_table {
* Store the information in a msgid (long) to allow us to find a
* sequence table entry from the msgid.
*/
-#define STORE_SEQ_IN_MSGID(seq, seqid) (((seq&0xff)<<26) | (seqid&0x3ffffff))
+#define STORE_SEQ_IN_MSGID(seq, seqid) \
+ ((((seq) & 0x3f) << 26) | ((seqid) & 0x3ffffff))
#define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \
do { \
- seq = ((msgid >> 26) & 0x3f); \
- seqid = (msgid & 0x3fffff); \
+ seq = (((msgid) >> 26) & 0x3f); \
+ seqid = ((msgid) & 0x3ffffff); \
} while (0)
-#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3fffff)
+#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3ffffff)
struct ipmi_channel {
unsigned char medium;
@@ -4645,3 +4646,4 @@ MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI"
" interface.");
MODULE_VERSION(IPMI_DRIVER_VERSION);
+MODULE_SOFTDEP("post: ipmi_devintf");
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index a112c0146012..2a7c425ddfa7 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -789,7 +789,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
smi_info->si_state = SI_NORMAL;
break;
}
- start_getting_msg_queue(smi_info);
+ start_getting_events(smi_info);
} else {
smi_info->si_state = SI_NORMAL;
}
@@ -812,7 +812,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
smi_info->si_state = SI_NORMAL;
break;
}
- start_getting_msg_queue(smi_info);
+ start_getting_events(smi_info);
} else {
smi_info->si_state = SI_NORMAL;
}
@@ -1764,7 +1764,7 @@ static int parse_str(const struct hotmod_vals *v, int *val, char *name,
s = strchr(*curr, ',');
if (!s) {
- printk(KERN_WARNING PFX "No hotmod %s given.\n", name);
+ pr_warn(PFX "No hotmod %s given.\n", name);
return -EINVAL;
}
*s = '\0';
@@ -1777,7 +1777,7 @@ static int parse_str(const struct hotmod_vals *v, int *val, char *name,
}
}
- printk(KERN_WARNING PFX "Invalid hotmod %s '%s'\n", name, *curr);
+ pr_warn(PFX "Invalid hotmod %s '%s'\n", name, *curr);
return -EINVAL;
}
@@ -1788,16 +1788,12 @@ static int check_hotmod_int_op(const char *curr, const char *option,
if (strcmp(curr, name) == 0) {
if (!option) {
- printk(KERN_WARNING PFX
- "No option given for '%s'\n",
- curr);
+ pr_warn(PFX "No option given for '%s'\n", curr);
return -EINVAL;
}
*val = simple_strtoul(option, &n, 0);
if ((*n != '\0') || (*option == '\0')) {
- printk(KERN_WARNING PFX
- "Bad option given for '%s'\n",
- curr);
+ pr_warn(PFX "Bad option given for '%s'\n", curr);
return -EINVAL;
}
return 1;
@@ -1877,8 +1873,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
}
addr = simple_strtoul(curr, &n, 0);
if ((*n != '\0') || (*curr == '\0')) {
- printk(KERN_WARNING PFX "Invalid hotmod address"
- " '%s'\n", curr);
+ pr_warn(PFX "Invalid hotmod address '%s'\n", curr);
break;
}
@@ -1921,9 +1916,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
continue;
rv = -EINVAL;
- printk(KERN_WARNING PFX
- "Invalid hotmod option '%s'\n",
- curr);
+ pr_warn(PFX "Invalid hotmod option '%s'\n", curr);
goto out;
}
@@ -2003,7 +1996,7 @@ static int hardcode_find_bmc(void)
return -ENOMEM;
info->addr_source = SI_HARDCODED;
- printk(KERN_INFO PFX "probing via hardcoded address\n");
+ pr_info(PFX "probing via hardcoded address\n");
if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
info->si_type = SI_KCS;
@@ -2012,9 +2005,8 @@ static int hardcode_find_bmc(void)
} else if (strcmp(si_type[i], "bt") == 0) {
info->si_type = SI_BT;
} else {
- printk(KERN_WARNING PFX "Interface type specified "
- "for interface %d, was invalid: %s\n",
- i, si_type[i]);
+ pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n",
+ i, si_type[i]);
kfree(info);
continue;
}
@@ -2030,9 +2022,8 @@ static int hardcode_find_bmc(void)
info->io.addr_data = addrs[i];
info->io.addr_type = IPMI_MEM_ADDR_SPACE;
} else {
- printk(KERN_WARNING PFX "Interface type specified "
- "for interface %d, but port and address were "
- "not set or set to zero.\n", i);
+ pr_warn(PFX "Interface type specified for interface %d, but port and address were not set or set to zero.\n",
+ i);
kfree(info);
continue;
}
@@ -2173,18 +2164,18 @@ static int try_init_spmi(struct SPMITable *spmi)
int rv;
if (spmi->IPMIlegacy != 1) {
- printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
+ pr_info(PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
return -ENODEV;
}
info = smi_info_alloc();
if (!info) {
- printk(KERN_ERR PFX "Could not allocate SI data (3)\n");
+ pr_err(PFX "Could not allocate SI data (3)\n");
return -ENOMEM;
}
info->addr_source = SI_SPMI;
- printk(KERN_INFO PFX "probing via SPMI\n");
+ pr_info(PFX "probing via SPMI\n");
/* Figure out the interface type. */
switch (spmi->InterfaceType) {
@@ -2201,8 +2192,8 @@ static int try_init_spmi(struct SPMITable *spmi)
kfree(info);
return -EIO;
default:
- printk(KERN_INFO PFX "Unknown ACPI/SPMI SI type %d\n",
- spmi->InterfaceType);
+ pr_info(PFX "Unknown ACPI/SPMI SI type %d\n",
+ spmi->InterfaceType);
kfree(info);
return -EIO;
}
@@ -2238,15 +2229,15 @@ static int try_init_spmi(struct SPMITable *spmi)
info->io.addr_type = IPMI_IO_ADDR_SPACE;
} else {
kfree(info);
- printk(KERN_WARNING PFX "Unknown ACPI I/O Address type\n");
+ pr_warn(PFX "Unknown ACPI I/O Address type\n");
return -EIO;
}
info->io.addr_data = spmi->addr.address;
pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n",
- (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
- info->io.addr_data, info->io.regsize, info->io.regspacing,
- info->irq);
+ (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
+ info->io.addr_data, info->io.regsize, info->io.regspacing,
+ info->irq);
rv = add_smi(info);
if (rv)
@@ -2356,12 +2347,12 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
info = smi_info_alloc();
if (!info) {
- printk(KERN_ERR PFX "Could not allocate SI data\n");
+ pr_err(PFX "Could not allocate SI data\n");
return;
}
info->addr_source = SI_SMBIOS;
- printk(KERN_INFO PFX "probing via SMBIOS\n");
+ pr_info(PFX "probing via SMBIOS\n");
switch (ipmi_data->type) {
case 0x01: /* KCS */
@@ -2391,8 +2382,8 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
default:
kfree(info);
- printk(KERN_WARNING PFX "Unknown SMBIOS I/O Address type: %d\n",
- ipmi_data->addr_space);
+ pr_warn(PFX "Unknown SMBIOS I/O Address type: %d\n",
+ ipmi_data->addr_space);
return;
}
info->io.addr_data = ipmi_data->base_addr;
@@ -2410,9 +2401,9 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
info->irq_setup = std_irq_setup;
pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
- (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
- info->io.addr_data, info->io.regsize, info->io.regspacing,
- info->irq);
+ (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
+ info->io.addr_data, info->io.regsize, info->io.regspacing,
+ info->irq);
if (add_smi(info))
kfree(info);
@@ -3141,9 +3132,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
rv = wait_for_msg_done(smi_info);
if (rv) {
- printk(KERN_WARNING PFX "Error getting response from get"
- " global enables command, the event buffer is not"
- " enabled.\n");
+ pr_warn(PFX "Error getting response from get global enables command, the event buffer is not enabled.\n");
goto out;
}
@@ -3154,8 +3143,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD ||
resp[2] != 0) {
- printk(KERN_WARNING PFX "Invalid return from get global"
- " enables command, cannot enable the event buffer.\n");
+ pr_warn(PFX "Invalid return from get global enables command, cannot enable the event buffer.\n");
rv = -EINVAL;
goto out;
}
@@ -3173,9 +3161,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
rv = wait_for_msg_done(smi_info);
if (rv) {
- printk(KERN_WARNING PFX "Error getting response from set"
- " global, enables command, the event buffer is not"
- " enabled.\n");
+ pr_warn(PFX "Error getting response from set global, enables command, the event buffer is not enabled.\n");
goto out;
}
@@ -3185,8 +3171,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
if (resp_len < 3 ||
resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
- printk(KERN_WARNING PFX "Invalid return from get global,"
- "enables command, not enable the event buffer.\n");
+ pr_warn(PFX "Invalid return from get global, enables command, not enable the event buffer.\n");
rv = -EINVAL;
goto out;
}
@@ -3463,8 +3448,16 @@ static int is_new_interface(struct smi_info *info)
list_for_each_entry(e, &smi_infos, link) {
if (e->io.addr_type != info->io.addr_type)
continue;
- if (e->io.addr_data == info->io.addr_data)
+ if (e->io.addr_data == info->io.addr_data) {
+ /*
+ * This is a cheap hack, ACPI doesn't have a defined
+ * slave address but SMBIOS does. Pick it up from
+ * any source that has it available.
+ */
+ if (info->slave_addr && !e->slave_addr)
+ e->slave_addr = info->slave_addr;
return 0;
+ }
}
return 1;
@@ -3474,17 +3467,18 @@ static int add_smi(struct smi_info *new_smi)
{
int rv = 0;
- printk(KERN_INFO PFX "Adding %s-specified %s state machine",
- ipmi_addr_src_to_str(new_smi->addr_source),
- si_to_str[new_smi->si_type]);
mutex_lock(&smi_infos_lock);
if (!is_new_interface(new_smi)) {
- printk(KERN_CONT " duplicate interface\n");
+ pr_info(PFX "%s-specified %s state machine: duplicate\n",
+ ipmi_addr_src_to_str(new_smi->addr_source),
+ si_to_str[new_smi->si_type]);
rv = -EBUSY;
goto out_err;
}
- printk(KERN_CONT "\n");
+ pr_info(PFX "Adding %s-specified %s state machine\n",
+ ipmi_addr_src_to_str(new_smi->addr_source),
+ si_to_str[new_smi->si_type]);
/* So we know not to free it unless we have allocated one. */
new_smi->intf = NULL;
@@ -3502,15 +3496,14 @@ static int try_smi_init(struct smi_info *new_smi)
{
int rv = 0;
int i;
+ char *init_name = NULL;
- printk(KERN_INFO PFX "Trying %s-specified %s state"
- " machine at %s address 0x%lx, slave address 0x%x,"
- " irq %d\n",
- ipmi_addr_src_to_str(new_smi->addr_source),
- si_to_str[new_smi->si_type],
- addr_space_to_str[new_smi->io.addr_type],
- new_smi->io.addr_data,
- new_smi->slave_addr, new_smi->irq);
+ pr_info(PFX "Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n",
+ ipmi_addr_src_to_str(new_smi->addr_source),
+ si_to_str[new_smi->si_type],
+ addr_space_to_str[new_smi->io.addr_type],
+ new_smi->io.addr_data,
+ new_smi->slave_addr, new_smi->irq);
switch (new_smi->si_type) {
case SI_KCS:
@@ -3531,11 +3524,30 @@ static int try_smi_init(struct smi_info *new_smi)
goto out_err;
}
+ /* Do this early so it's available for logs. */
+ if (!new_smi->dev) {
+ init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", 0);
+
+ /*
+ * If we don't already have a device from something
+ * else (like PCI), then register a new one.
+ */
+ new_smi->pdev = platform_device_alloc("ipmi_si",
+ new_smi->intf_num);
+ if (!new_smi->pdev) {
+ pr_err(PFX "Unable to allocate platform device\n");
+ goto out_err;
+ }
+ new_smi->dev = &new_smi->pdev->dev;
+ new_smi->dev->driver = &ipmi_driver.driver;
+ /* Nulled by device_add() */
+ new_smi->dev->init_name = init_name;
+ }
+
/* Allocate the state machine's data and initialize it. */
new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL);
if (!new_smi->si_sm) {
- printk(KERN_ERR PFX
- "Could not allocate state machine memory\n");
+ pr_err(PFX "Could not allocate state machine memory\n");
rv = -ENOMEM;
goto out_err;
}
@@ -3545,14 +3557,14 @@ static int try_smi_init(struct smi_info *new_smi)
/* Now that we know the I/O size, we can set up the I/O. */
rv = new_smi->io_setup(new_smi);
if (rv) {
- printk(KERN_ERR PFX "Could not set up I/O space\n");
+ dev_err(new_smi->dev, "Could not set up I/O space\n");
goto out_err;
}
/* Do low-level detection first. */
if (new_smi->handlers->detect(new_smi->si_sm)) {
if (new_smi->addr_source)
- printk(KERN_INFO PFX "Interface detection failed\n");
+ dev_err(new_smi->dev, "Interface detection failed\n");
rv = -ENODEV;
goto out_err;
}
@@ -3564,8 +3576,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = try_get_dev_id(new_smi);
if (rv) {
if (new_smi->addr_source)
- printk(KERN_INFO PFX "There appears to be no BMC"
- " at this location\n");
+ dev_err(new_smi->dev, "There appears to be no BMC at this location\n");
goto out_err;
}
@@ -3604,27 +3615,12 @@ static int try_smi_init(struct smi_info *new_smi)
atomic_set(&new_smi->req_events, 1);
}
- if (!new_smi->dev) {
- /*
- * If we don't already have a device from something
- * else (like PCI), then register a new one.
- */
- new_smi->pdev = platform_device_alloc("ipmi_si",
- new_smi->intf_num);
- if (!new_smi->pdev) {
- printk(KERN_ERR PFX
- "Unable to allocate platform device\n");
- goto out_err;
- }
- new_smi->dev = &new_smi->pdev->dev;
- new_smi->dev->driver = &ipmi_driver.driver;
-
+ if (new_smi->pdev) {
rv = platform_device_add(new_smi->pdev);
if (rv) {
- printk(KERN_ERR PFX
- "Unable to register system interface device:"
- " %d\n",
- rv);
+ dev_err(new_smi->dev,
+ "Unable to register system interface device: %d\n",
+ rv);
goto out_err;
}
new_smi->dev_registered = true;
@@ -3668,6 +3664,9 @@ static int try_smi_init(struct smi_info *new_smi)
dev_info(new_smi->dev, "IPMI %s interface initialized\n",
si_to_str[new_smi->si_type]);
+ WARN_ON(new_smi->dev->init_name != NULL);
+ kfree(init_name);
+
return 0;
out_err_stop_timer:
@@ -3712,8 +3711,14 @@ out_err:
if (new_smi->dev_registered) {
platform_device_unregister(new_smi->pdev);
new_smi->dev_registered = false;
+ new_smi->pdev = NULL;
+ } else if (new_smi->pdev) {
+ platform_device_put(new_smi->pdev);
+ new_smi->pdev = NULL;
}
+ kfree(init_name);
+
return rv;
}
@@ -3732,8 +3737,7 @@ static int init_ipmi_si(void)
if (si_tryplatform) {
rv = platform_driver_register(&ipmi_driver);
if (rv) {
- printk(KERN_ERR PFX "Unable to register "
- "driver: %d\n", rv);
+ pr_err(PFX "Unable to register driver: %d\n", rv);
return rv;
}
}
@@ -3753,7 +3757,7 @@ static int init_ipmi_si(void)
}
}
- printk(KERN_INFO "IPMI System Interface driver.\n");
+ pr_info("IPMI System Interface driver.\n");
/* If the user gave us a device, they presumably want us to use it */
if (!hardcode_find_bmc())
@@ -3763,8 +3767,7 @@ static int init_ipmi_si(void)
if (si_trypci) {
rv = pci_register_driver(&ipmi_pci_driver);
if (rv)
- printk(KERN_ERR PFX "Unable to register "
- "PCI driver: %d\n", rv);
+ pr_err(PFX "Unable to register PCI driver: %d\n", rv);
else
pci_registered = true;
}
@@ -3826,8 +3829,7 @@ static int init_ipmi_si(void)
if (unload_when_empty && list_empty(&smi_infos)) {
mutex_unlock(&smi_infos_lock);
cleanup_ipmi_si();
- printk(KERN_WARNING PFX
- "Unable to find any System Interface(s)\n");
+ pr_warn(PFX "Unable to find any System Interface(s)\n");
return -ENODEV;
} else {
mutex_unlock(&smi_infos_lock);
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 5673ffff00be..cca6e5bc1cea 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -174,7 +174,6 @@ enum ssif_stat_indexes {
};
struct ssif_addr_info {
- unsigned short addr;
struct i2c_board_info binfo;
char *adapter_name;
int debug;
@@ -1154,10 +1153,6 @@ static bool ssif_dbg_probe;
module_param_named(dbg_probe, ssif_dbg_probe, bool, 0);
MODULE_PARM_DESC(dbg_probe, "Enable debugging of probing of adapters.");
-static int use_thread;
-module_param(use_thread, int, 0);
-MODULE_PARM_DESC(use_thread, "Use the thread interface.");
-
static bool ssif_tryacpi = true;
module_param_named(tryacpi, ssif_tryacpi, bool, 0);
MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI");
@@ -1405,6 +1400,34 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
return false;
}
+static int find_slave_address(struct i2c_client *client, int slave_addr)
+{
+ struct ssif_addr_info *info;
+
+ if (slave_addr)
+ return slave_addr;
+
+ /*
+ * Came in without a slave address, search around to see if
+ * the other sources have a slave address. This lets us pick
+ * up an SMBIOS slave address when using ACPI.
+ */
+ list_for_each_entry(info, &ssif_infos, link) {
+ if (info->binfo.addr != client->addr)
+ continue;
+ if (info->adapter_name && client->adapter->name &&
+ strcmp_nospace(info->adapter_name,
+ client->adapter->name))
+ continue;
+ if (info->slave_addr) {
+ slave_addr = info->slave_addr;
+ break;
+ }
+ }
+
+ return slave_addr;
+}
+
/*
* Global enables we care about.
*/
@@ -1447,6 +1470,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
+ slave_addr = find_slave_address(client, slave_addr);
+
pr_info(PFX "Trying %s-specified SSIF interface at i2c address 0x%x, adapter %s, slave address 0x%x\n",
ipmi_addr_src_to_str(ssif_info->addr_source),
client->addr, client->adapter->name, slave_addr);
@@ -1935,7 +1960,7 @@ static int decode_dmi(const struct dmi_device *dmi_dev)
slave_addr = data[6];
}
- return new_ssif_client(myaddr, NULL, 0, 0, SI_SMBIOS);
+ return new_ssif_client(myaddr, NULL, 0, slave_addr, SI_SMBIOS);
}
static void dmi_iterator(void)
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 97ae60fa1584..bb8a77a5985f 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -448,12 +448,20 @@ EXPORT_SYMBOL(clk_register_clkdev);
*
* con_id or dev_id may be NULL as a wildcard, just as in the rest of
* clkdev.
+ *
+ * To make things easier for mass registration, we detect error clk_hws
+ * from a previous clk_hw_register_*() call, and return the error code for
+ * those. This is to permit this function to be called immediately
+ * after clk_hw_register_*().
*/
int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
const char *dev_id)
{
struct clk_lookup *cl;
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
/*
* Since dev_id can be NULL, and NULL is handled specially, we must
* pass it as either a NULL format string, or with "%s".
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
index 6a964144a5b5..cbce308aad04 100644
--- a/drivers/clk/imx/clk-imx31.c
+++ b/drivers/clk/imx/clk-imx31.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <soc/imx/revision.h>
#include <soc/imx/timer.h>
#include <asm/irq.h>
@@ -72,14 +73,8 @@ static struct clk ** const uart_clks[] __initconst = {
NULL
};
-static void __init _mx31_clocks_init(unsigned long fref)
+static void __init _mx31_clocks_init(void __iomem *base, unsigned long fref)
{
- void __iomem *base;
- struct device_node *np;
-
- base = ioremap(MX31_CCM_BASE_ADDR, SZ_4K);
- BUG_ON(!base);
-
clk[dummy] = imx_clk_fixed("dummy", 0);
clk[ckih] = imx_clk_fixed("ckih", fref);
clk[ckil] = imx_clk_fixed("ckil", 32768);
@@ -147,21 +142,17 @@ static void __init _mx31_clocks_init(unsigned long fref)
clk_prepare_enable(clk[iim_gate]);
mx31_revision();
clk_disable_unprepare(clk[iim_gate]);
-
- np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
-
- if (np) {
- clk_data.clks = clk;
- clk_data.clk_num = ARRAY_SIZE(clk);
- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
- }
}
-int __init mx31_clocks_init(void)
+int __init mx31_clocks_init(unsigned long fref)
{
- u32 fref = 26000000; /* default */
+ void __iomem *base;
+
+ base = ioremap(MX31_CCM_BASE_ADDR, SZ_4K);
+ if (!base)
+ panic("%s: failed to map registers\n", __func__);
- _mx31_clocks_init(fref);
+ _mx31_clocks_init(base, fref);
clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
@@ -224,22 +215,31 @@ int __init mx31_clocks_init(void)
return 0;
}
-int __init mx31_clocks_init_dt(void)
+static void __init mx31_clocks_init_dt(struct device_node *np)
{
- struct device_node *np;
+ struct device_node *osc_np;
u32 fref = 26000000; /* default */
+ void __iomem *ccm;
- for_each_compatible_node(np, NULL, "fixed-clock") {
- if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
+ for_each_compatible_node(osc_np, NULL, "fixed-clock") {
+ if (!of_device_is_compatible(osc_np, "fsl,imx-osc26m"))
continue;
- if (!of_property_read_u32(np, "clock-frequency", &fref)) {
- of_node_put(np);
+ if (!of_property_read_u32(osc_np, "clock-frequency", &fref)) {
+ of_node_put(osc_np);
break;
}
}
- _mx31_clocks_init(fref);
+ ccm = of_iomap(np, 0);
+ if (!ccm)
+ panic("%s: failed to map registers\n", __func__);
- return 0;
+ _mx31_clocks_init(ccm, fref);
+
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
+
+CLK_OF_DECLARE(imx31_ccm, "fsl,imx31-ccm", mx31_clocks_init_dt);
diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c
index c53993b6bf87..6416c1f8e632 100644
--- a/drivers/clk/pxa/clk-pxa25x.c
+++ b/drivers/clk/pxa/clk-pxa25x.c
@@ -322,7 +322,7 @@ static struct dummy_clk dummy_clks[] __initdata = {
DUMMY_CLK("GPIO11_CLK", NULL, "osc_3_6864mhz"),
DUMMY_CLK("GPIO12_CLK", NULL, "osc_32_768khz"),
DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
- DUMMY_CLK("OSTIMER0", NULL, "osc_32_768khz"),
+ DUMMY_CLK("OSTIMER0", NULL, "osc_3_6864mhz"),
DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index e2c6e43cf8ca..4866f7aa32e6 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -282,6 +282,26 @@ config CLKSRC_MPS2
select CLKSRC_MMIO
select CLKSRC_OF
+config ARC_TIMERS
+ bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST
+ depends on GENERIC_CLOCKEVENTS
+ select CLKSRC_OF
+ help
+ These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores
+ (ARC700 as well as ARC HS38).
+ TIMER0 serves as clockevent while TIMER1 provides clocksource
+
+config ARC_TIMERS_64BIT
+ bool "Support for 64-bit counters in ARC HS38 cores" if COMPILE_TEST
+ depends on GENERIC_CLOCKEVENTS
+ depends on ARC_TIMERS
+ select CLKSRC_OF
+ help
+ This enables 2 different 64-bit timers: RTC (for UP) and GFRC (for SMP)
+ RTC is implemented inside the core, while GFRC sits outside the core in
+ ARConnect IP block. Driver automatically picks one of them for clocksource
+ as appropriate.
+
config ARM_ARCH_TIMER
bool
select CLKSRC_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cf87f407f1ad..a14111e1f087 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o
obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o
obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o
+obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o
diff --git a/arch/arc/kernel/time.c b/drivers/clocksource/arc_timer.c
index c10390d1ddb6..a49748d826c0 100644
--- a/arch/arc/kernel/time.c
+++ b/drivers/clocksource/arc_timer.c
@@ -1,32 +1,18 @@
/*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.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.
- *
- * vineetg: Jan 1011
- * -sched_clock( ) no longer jiffies based. Uses the same clocksource
- * as gtod
- *
- * Rajeshwarr/Vineetg: Mar 2008
- * -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
- * for arch independent gettimeofday()
- * -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
- *
- * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
*/
-/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
- * Each can programmed to go from @count to @limit and optionally
- * interrupt when that happens.
- * A write to Control Register clears the Interrupt
+/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be
+ * programmed to go from @count to @limit and optionally interrupt.
+ * We've designated TIMER0 for clockevents and TIMER1 for clocksource
*
- * We've designated TIMER0 for events (clockevents)
- * while TIMER1 for free running (clocksource)
- *
- * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
- * which however is currently broken
+ * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP)
+ * which are suitable for UP and SMP based clocksources respectively
*/
#include <linux/interrupt.h>
@@ -37,23 +23,10 @@
#include <linux/cpu.h>
#include <linux/of.h>
#include <linux/of_irq.h>
-#include <asm/irq.h>
-#include <asm/arcregs.h>
-
-#include <asm/mcip.h>
-/* Timer related Aux registers */
-#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
-#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
-#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
-#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
-#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
-#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
+#include <soc/arc/timers.h>
+#include <soc/arc/mcip.h>
-#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */
-#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
-
-#define ARC_TIMER_MAX 0xFFFFFFFF
static unsigned long arc_timer_freq;
@@ -81,31 +54,24 @@ static int noinline arc_get_timer_clk(struct device_node *node)
/********** Clock Source Device *********/
-#ifdef CONFIG_ARC_HAS_GFRC
+#ifdef CONFIG_ARC_TIMERS_64BIT
static cycle_t arc_read_gfrc(struct clocksource *cs)
{
unsigned long flags;
- union {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- struct { u32 h, l; };
-#else
- struct { u32 l, h; };
-#endif
- cycle_t full;
- } stamp;
+ u32 l, h;
local_irq_save(flags);
__mcip_cmd(CMD_GFRC_READ_LO, 0);
- stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK);
+ l = read_aux_reg(ARC_REG_MCIP_READBACK);
__mcip_cmd(CMD_GFRC_READ_HI, 0);
- stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK);
+ h = read_aux_reg(ARC_REG_MCIP_READBACK);
local_irq_restore(flags);
- return stamp.full;
+ return (((cycle_t)h) << 32) | l;
}
static struct clocksource arc_counter_gfrc = {
@@ -118,11 +84,14 @@ static struct clocksource arc_counter_gfrc = {
static int __init arc_cs_setup_gfrc(struct device_node *node)
{
- int exists = cpuinfo_arc700[0].extn.gfrc;
+ struct mcip_bcr mp;
int ret;
- if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
+ READ_BCR(ARC_REG_MCIP_BCR, mp);
+ if (!mp.gfrc) {
+ pr_warn("Global-64-bit-Ctr clocksource not detected");
return -ENXIO;
+ }
ret = arc_get_timer_clk(node);
if (ret)
@@ -132,10 +101,6 @@ static int __init arc_cs_setup_gfrc(struct device_node *node)
}
CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
-#endif
-
-#ifdef CONFIG_ARC_HAS_RTC
-
#define AUX_RTC_CTRL 0x103
#define AUX_RTC_LOW 0x104
#define AUX_RTC_HIGH 0x105
@@ -143,14 +108,7 @@ CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
static cycle_t arc_read_rtc(struct clocksource *cs)
{
unsigned long status;
- union {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- struct { u32 high, low; };
-#else
- struct { u32 low, high; };
-#endif
- cycle_t full;
- } stamp;
+ u32 l, h;
/*
* hardware has an internal state machine which tracks readout of
@@ -159,12 +117,12 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
* - high increments after low has been read
*/
do {
- stamp.low = read_aux_reg(AUX_RTC_LOW);
- stamp.high = read_aux_reg(AUX_RTC_HIGH);
+ l = read_aux_reg(AUX_RTC_LOW);
+ h = read_aux_reg(AUX_RTC_HIGH);
status = read_aux_reg(AUX_RTC_CTRL);
} while (!(status & _BITUL(31)));
- return stamp.full;
+ return (((cycle_t)h) << 32) | l;
}
static struct clocksource arc_counter_rtc = {
@@ -177,15 +135,20 @@ static struct clocksource arc_counter_rtc = {
static int __init arc_cs_setup_rtc(struct device_node *node)
{
- int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
+ struct bcr_timer timer;
int ret;
- if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
+ READ_BCR(ARC_REG_TIMERS_BCR, timer);
+ if (!timer.rtc) {
+ pr_warn("Local-64-bit-Ctr clocksource not detected");
return -ENXIO;
+ }
/* Local to CPU hence not usable in SMP */
- if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP"))
+ if (IS_ENABLED(CONFIG_SMP)) {
+ pr_warn("Local-64-bit-Ctr not usable in SMP");
return -EINVAL;
+ }
ret = arc_get_timer_clk(node);
if (ret)
@@ -228,7 +191,7 @@ static int __init arc_cs_setup_timer1(struct device_node *node)
if (ret)
return ret;
- write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
+ write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX);
write_aux_reg(ARC_REG_TIMER1_CNT, 0);
write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
@@ -306,7 +269,7 @@ static int arc_timer_starting_cpu(unsigned int cpu)
evt->cpumask = cpumask_of(smp_processor_id());
- clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
+ clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMERN_MAX);
enable_percpu_irq(arc_timer_irq, 0);
return 0;
}
@@ -371,12 +334,3 @@ static int __init arc_of_timer_init(struct device_node *np)
return ret;
}
CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);
-
-/*
- * Called from start_kernel() - boot CPU only
- */
-void __init time_init(void)
-{
- of_clk_init(NULL);
- clocksource_probe();
-}
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/pxa_timer.c
index 3e1cb512f3ce..9cae38eebec2 100644
--- a/drivers/clocksource/pxa_timer.c
+++ b/drivers/clocksource/pxa_timer.c
@@ -220,17 +220,16 @@ CLOCKSOURCE_OF_DECLARE(pxa_timer, "marvell,pxa-timer", pxa_timer_dt_init);
/*
* Legacy timer init for non device-tree boards.
*/
-void __init pxa_timer_nodt_init(int irq, void __iomem *base,
- unsigned long clock_tick_rate)
+void __init pxa_timer_nodt_init(int irq, void __iomem *base)
{
struct clk *clk;
timer_base = base;
clk = clk_get(NULL, "OSTIMER0");
- if (clk && !IS_ERR(clk))
+ if (clk && !IS_ERR(clk)) {
clk_prepare_enable(clk);
- else
+ pxa_timer_common_init(irq, clk_get_rate(clk));
+ } else {
pr_crit("%s: unable to get clk\n", __func__);
-
- pxa_timer_common_init(irq, clock_tick_rate);
+ }
}
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
index 70c149af8ee0..8da5e93b6810 100644
--- a/drivers/clocksource/timer-nps.c
+++ b/drivers/clocksource/timer-nps.c
@@ -46,7 +46,36 @@
/* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
-static unsigned long nps_timer_rate;
+static int __init nps_get_timer_clk(struct device_node *node,
+ unsigned long *timer_freq,
+ struct clk **clk)
+{
+ int ret;
+
+ *clk = of_clk_get(node, 0);
+ ret = PTR_ERR_OR_ZERO(*clk);
+ if (ret) {
+ pr_err("timer missing clk");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(*clk);
+ if (ret) {
+ pr_err("Couldn't enable parent clk\n");
+ clk_put(*clk);
+ return ret;
+ }
+
+ *timer_freq = clk_get_rate(*clk);
+ if (!(*timer_freq)) {
+ pr_err("Couldn't get clk rate\n");
+ clk_disable_unprepare(*clk);
+ clk_put(*clk);
+ return -EINVAL;
+ }
+
+ return 0;
+}
static cycle_t nps_clksrc_read(struct clocksource *clksrc)
{
@@ -55,26 +84,24 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc)
return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
}
-static int __init nps_setup_clocksource(struct device_node *node,
- struct clk *clk)
+static int __init nps_setup_clocksource(struct device_node *node)
{
int ret, cluster;
+ struct clk *clk;
+ unsigned long nps_timer1_freq;
+
for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
nps_msu_reg_low_addr[cluster] =
nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
- NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
+ NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
- ret = clk_prepare_enable(clk);
- if (ret) {
- pr_err("Couldn't enable parent clock\n");
+ ret = nps_get_timer_clk(node, &nps_timer1_freq, &clk);
+ if (ret)
return ret;
- }
-
- nps_timer_rate = clk_get_rate(clk);
- ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
- nps_timer_rate, 301, 32, nps_clksrc_read);
+ ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
+ nps_timer1_freq, 300, 32, nps_clksrc_read);
if (ret) {
pr_err("Couldn't register clock source.\n");
clk_disable_unprepare(clk);
@@ -83,18 +110,175 @@ static int __init nps_setup_clocksource(struct device_node *node,
return ret;
}
-static int __init nps_timer_init(struct device_node *node)
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
+ nps_setup_clocksource);
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clk_src, "ezchip,nps400-timer1",
+ nps_setup_clocksource);
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#include <soc/nps/mtm.h>
+
+/* Timer related Aux registers */
+#define NPS_REG_TIMER0_TSI 0xFFFFF850
+#define NPS_REG_TIMER0_LIMIT 0x23
+#define NPS_REG_TIMER0_CTRL 0x22
+#define NPS_REG_TIMER0_CNT 0x21
+
+/*
+ * Interrupt Enabled (IE) - re-arm the timer
+ * Not Halted (NH) - is cleared when working with JTAG (for debug)
+ */
+#define TIMER0_CTRL_IE BIT(0)
+#define TIMER0_CTRL_NH BIT(1)
+
+static unsigned long nps_timer0_freq;
+static unsigned long nps_timer0_irq;
+
+static void nps_clkevent_rm_thread(void)
+{
+ int thread;
+ unsigned int cflags, enabled_threads;
+
+ hw_schd_save(&cflags);
+
+ enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI);
+
+ /* remove thread from TSI1 */
+ thread = read_aux_reg(CTOP_AUX_THREAD_ID);
+ enabled_threads &= ~(1 << thread);
+ write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads);
+
+ /* Acknowledge and if needed re-arm the timer */
+ if (!enabled_threads)
+ write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH);
+ else
+ write_aux_reg(NPS_REG_TIMER0_CTRL,
+ TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+
+ hw_schd_restore(cflags);
+}
+
+static void nps_clkevent_add_thread(unsigned long delta)
+{
+ int thread;
+ unsigned int cflags, enabled_threads;
+
+ hw_schd_save(&cflags);
+
+ /* add thread to TSI1 */
+ thread = read_aux_reg(CTOP_AUX_THREAD_ID);
+ enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI);
+ enabled_threads |= (1 << thread);
+ write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads);
+
+ /* set next timer event */
+ write_aux_reg(NPS_REG_TIMER0_LIMIT, delta);
+ write_aux_reg(NPS_REG_TIMER0_CNT, 0);
+ write_aux_reg(NPS_REG_TIMER0_CTRL,
+ TIMER0_CTRL_IE | TIMER0_CTRL_NH);
+
+ hw_schd_restore(cflags);
+}
+
+/*
+ * Whenever anyone tries to change modes, we just mask interrupts
+ * and wait for the next event to get set.
+ */
+static int nps_clkevent_set_state(struct clock_event_device *dev)
+{
+ nps_clkevent_rm_thread();
+ disable_percpu_irq(nps_timer0_irq);
+
+ return 0;
+}
+
+static int nps_clkevent_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ nps_clkevent_add_thread(delta);
+ enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE);
+
+ return 0;
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
+ .name = "NPS Timer0",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 300,
+ .set_next_event = nps_clkevent_set_next_event,
+ .set_state_oneshot = nps_clkevent_set_state,
+ .set_state_oneshot_stopped = nps_clkevent_set_state,
+ .set_state_shutdown = nps_clkevent_set_state,
+ .tick_resume = nps_clkevent_set_state,
+};
+
+static irqreturn_t timer_irq_handler(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ nps_clkevent_rm_thread();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static int nps_timer_starting_cpu(unsigned int cpu)
+{
+ struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
+
+ evt->cpumask = cpumask_of(smp_processor_id());
+
+ clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX);
+ enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE);
+
+ return 0;
+}
+
+static int nps_timer_dying_cpu(unsigned int cpu)
+{
+ disable_percpu_irq(nps_timer0_irq);
+ return 0;
+}
+
+static int __init nps_setup_clockevent(struct device_node *node)
{
struct clk *clk;
+ int ret;
- clk = of_clk_get(node, 0);
- if (IS_ERR(clk)) {
- pr_err("Can't get timer clock.\n");
- return PTR_ERR(clk);
+ nps_timer0_irq = irq_of_parse_and_map(node, 0);
+ if (nps_timer0_irq <= 0) {
+ pr_err("clockevent: missing irq");
+ return -EINVAL;
}
- return nps_setup_clocksource(node, clk);
+ ret = nps_get_timer_clk(node, &nps_timer0_freq, &clk);
+ if (ret)
+ return ret;
+
+ /* Needs apriori irq_set_percpu_devid() done in intc map function */
+ ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
+ "Timer0 (per-cpu-tick)",
+ &nps_clockevent_device);
+ if (ret) {
+ pr_err("Couldn't request irq\n");
+ clk_disable_unprepare(clk);
+ return ret;
+ }
+
+ ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING,
+ "clockevents/nps:starting",
+ nps_timer_starting_cpu,
+ nps_timer_dying_cpu);
+ if (ret) {
+ pr_err("Failed to setup hotplug state");
+ clk_disable_unprepare(clk);
+ free_percpu_irq(nps_timer0_irq, &nps_clockevent_device);
+ return ret;
+ }
+
+ return 0;
}
-CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
- nps_timer_init);
+CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clk_evt, "ezchip,nps400-timer0",
+ nps_setup_clockevent);
+#endif /* CONFIG_EZNPS_MTM_EXT */
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 2154ea3c5d1c..263495d0adbd 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -494,7 +494,7 @@ config TEGRA20_APB_DMA
or vice versa. It does not support memory to memory data transfer.
config TEGRA210_ADMA
- bool "NVIDIA Tegra210 ADMA support"
+ tristate "NVIDIA Tegra210 ADMA support"
depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST) && PM_CLK
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 939a7c31f760..0b7c6ce629a6 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1793,6 +1793,13 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
}
EXPORT_SYMBOL_GPL(pl08x_filter_id);
+static bool pl08x_filter_fn(struct dma_chan *chan, void *chan_id)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+
+ return plchan->cd == chan_id;
+}
+
/*
* Just check that the device is there and active
* TODO: turn this bit on/off depending on the number of physical channels
@@ -2307,6 +2314,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
ret = -EINVAL;
goto out_no_platdata;
}
+ } else {
+ pl08x->slave.filter.map = pl08x->pd->slave_map;
+ pl08x->slave.filter.mapcnt = pl08x->pd->slave_map_len;
+ pl08x->slave.filter.fn = pl08x_filter_fn;
}
/* By default, AHB1 only. If dualmaster, from platform */
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index a4c8f80db29d..1baf3404a365 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -111,9 +111,8 @@ static struct at_desc *atc_alloc_descriptor(struct dma_chan *chan,
struct at_dma *atdma = to_at_dma(chan->device);
dma_addr_t phys;
- desc = dma_pool_alloc(atdma->dma_desc_pool, gfp_flags, &phys);
+ desc = dma_pool_zalloc(atdma->dma_desc_pool, gfp_flags, &phys);
if (desc) {
- memset(desc, 0, sizeof(struct at_desc));
INIT_LIST_HEAD(&desc->tx_list);
dma_async_tx_descriptor_init(&desc->txd, chan);
/* txd.flags will be overwritten in prep functions */
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index b7d7f2d443a1..7d4e0bcda9af 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -221,7 +221,6 @@ struct at_xdmac {
int irq;
struct clk *clk;
u32 save_gim;
- u32 save_gs;
struct dma_pool *at_xdmac_desc_pool;
struct at_xdmac_chan chan[0];
};
@@ -444,9 +443,8 @@ static struct at_xdmac_desc *at_xdmac_alloc_desc(struct dma_chan *chan,
struct at_xdmac *atxdmac = to_at_xdmac(chan->device);
dma_addr_t phys;
- desc = dma_pool_alloc(atxdmac->at_xdmac_desc_pool, gfp_flags, &phys);
+ desc = dma_pool_zalloc(atxdmac->at_xdmac_desc_pool, gfp_flags, &phys);
if (desc) {
- memset(desc, 0, sizeof(*desc));
INIT_LIST_HEAD(&desc->descs_list);
dma_async_tx_descriptor_init(&desc->tx_dma_desc, chan);
desc->tx_dma_desc.tx_submit = at_xdmac_tx_submit;
@@ -1896,7 +1894,6 @@ static int atmel_xdmac_resume(struct device *dev)
}
at_xdmac_write(atxdmac, AT_XDMAC_GIE, atxdmac->save_gim);
- at_xdmac_write(atxdmac, AT_XDMAC_GE, atxdmac->save_gs);
list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
atchan = to_at_xdmac_chan(chan);
at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index cf76fc6149e5..451f899f74e4 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -164,7 +164,9 @@ struct dmatest_thread {
struct task_struct *task;
struct dma_chan *chan;
u8 **srcs;
+ u8 **usrcs;
u8 **dsts;
+ u8 **udsts;
enum dma_transaction_type type;
bool done;
};
@@ -431,6 +433,7 @@ static int dmatest_func(void *data)
ktime_t comparetime = ktime_set(0, 0);
s64 runtime = 0;
unsigned long long total_len = 0;
+ u8 align = 0;
set_freezable();
@@ -441,20 +444,24 @@ static int dmatest_func(void *data)
params = &info->params;
chan = thread->chan;
dev = chan->device;
- if (thread->type == DMA_MEMCPY)
+ if (thread->type == DMA_MEMCPY) {
+ align = dev->copy_align;
src_cnt = dst_cnt = 1;
- else if (thread->type == DMA_SG)
+ } else if (thread->type == DMA_SG) {
+ align = dev->copy_align;
src_cnt = dst_cnt = sg_buffers;
- else if (thread->type == DMA_XOR) {
+ } else if (thread->type == DMA_XOR) {
/* force odd to ensure dst = src */
src_cnt = min_odd(params->xor_sources | 1, dev->max_xor);
dst_cnt = 1;
+ align = dev->xor_align;
} else if (thread->type == DMA_PQ) {
/* force odd to ensure dst = src */
src_cnt = min_odd(params->pq_sources | 1, dma_maxpq(dev, 0));
dst_cnt = 2;
+ align = dev->pq_align;
- pq_coefs = kmalloc(params->pq_sources+1, GFP_KERNEL);
+ pq_coefs = kmalloc(params->pq_sources + 1, GFP_KERNEL);
if (!pq_coefs)
goto err_thread_type;
@@ -463,23 +470,47 @@ static int dmatest_func(void *data)
} else
goto err_thread_type;
- thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ thread->srcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
if (!thread->srcs)
goto err_srcs;
+
+ thread->usrcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->usrcs)
+ goto err_usrcs;
+
for (i = 0; i < src_cnt; i++) {
- thread->srcs[i] = kmalloc(params->buf_size, GFP_KERNEL);
- if (!thread->srcs[i])
+ thread->usrcs[i] = kmalloc(params->buf_size + align,
+ GFP_KERNEL);
+ if (!thread->usrcs[i])
goto err_srcbuf;
+
+ /* align srcs to alignment restriction */
+ if (align)
+ thread->srcs[i] = PTR_ALIGN(thread->usrcs[i], align);
+ else
+ thread->srcs[i] = thread->usrcs[i];
}
thread->srcs[i] = NULL;
- thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ thread->dsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
if (!thread->dsts)
goto err_dsts;
+
+ thread->udsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->udsts)
+ goto err_udsts;
+
for (i = 0; i < dst_cnt; i++) {
- thread->dsts[i] = kmalloc(params->buf_size, GFP_KERNEL);
- if (!thread->dsts[i])
+ thread->udsts[i] = kmalloc(params->buf_size + align,
+ GFP_KERNEL);
+ if (!thread->udsts[i])
goto err_dstbuf;
+
+ /* align dsts to alignment restriction */
+ if (align)
+ thread->dsts[i] = PTR_ALIGN(thread->udsts[i], align);
+ else
+ thread->dsts[i] = thread->udsts[i];
}
thread->dsts[i] = NULL;
@@ -498,20 +529,11 @@ static int dmatest_func(void *data)
dma_addr_t srcs[src_cnt];
dma_addr_t *dsts;
unsigned int src_off, dst_off, len;
- u8 align = 0;
struct scatterlist tx_sg[src_cnt];
struct scatterlist rx_sg[src_cnt];
total_tests++;
- /* honor alignment restrictions */
- if (thread->type == DMA_MEMCPY || thread->type == DMA_SG)
- align = dev->copy_align;
- else if (thread->type == DMA_XOR)
- align = dev->xor_align;
- else if (thread->type == DMA_PQ)
- align = dev->pq_align;
-
if (1 << align > params->buf_size) {
pr_err("%u-byte buffer too small for %d-byte alignment\n",
params->buf_size, 1 << align);
@@ -549,7 +571,7 @@ static int dmatest_func(void *data)
filltime = ktime_add(filltime, diff);
}
- um = dmaengine_get_unmap_data(dev->dev, src_cnt+dst_cnt,
+ um = dmaengine_get_unmap_data(dev->dev, src_cnt + dst_cnt,
GFP_KERNEL);
if (!um) {
failed_tests++;
@@ -729,13 +751,17 @@ static int dmatest_func(void *data)
ret = 0;
err_dstbuf:
- for (i = 0; thread->dsts[i]; i++)
- kfree(thread->dsts[i]);
+ for (i = 0; thread->udsts[i]; i++)
+ kfree(thread->udsts[i]);
+ kfree(thread->udsts);
+err_udsts:
kfree(thread->dsts);
err_dsts:
err_srcbuf:
- for (i = 0; thread->srcs[i]; i++)
- kfree(thread->srcs[i]);
+ for (i = 0; thread->usrcs[i]; i++)
+ kfree(thread->usrcs[i]);
+ kfree(thread->usrcs);
+err_usrcs:
kfree(thread->srcs);
err_srcs:
kfree(pq_coefs);
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index c2c0a613cb7a..e5adf5d1c34f 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -1569,7 +1569,7 @@ int dw_dma_probe(struct dw_dma_chip *chip)
(dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
} else {
dwc->block_size = pdata->block_size;
- dwc->nollp = pdata->is_nollp;
+ dwc->nollp = !pdata->multi_block[i];
}
}
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index 5bda0eb9f393..b1655e40cfa2 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -102,7 +102,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct dw_dma_platform_data *pdata;
- u32 tmp, arr[DW_DMA_MAX_NR_MASTERS];
+ u32 tmp, arr[DW_DMA_MAX_NR_MASTERS], mb[DW_DMA_MAX_NR_CHANNELS];
u32 nr_masters;
u32 nr_channels;
@@ -118,6 +118,8 @@ dw_dma_parse_dt(struct platform_device *pdev)
if (of_property_read_u32(np, "dma-channels", &nr_channels))
return NULL;
+ if (nr_channels > DW_DMA_MAX_NR_CHANNELS)
+ return NULL;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -129,6 +131,12 @@ dw_dma_parse_dt(struct platform_device *pdev)
if (of_property_read_bool(np, "is_private"))
pdata->is_private = true;
+ /*
+ * All known devices, which use DT for configuration, support
+ * memory-to-memory transfers. So enable it by default.
+ */
+ pdata->is_memcpy = true;
+
if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
pdata->chan_allocation_order = (unsigned char)tmp;
@@ -146,6 +154,14 @@ dw_dma_parse_dt(struct platform_device *pdev)
pdata->data_width[tmp] = BIT(arr[tmp] & 0x07);
}
+ if (!of_property_read_u32_array(np, "multi-block", mb, nr_channels)) {
+ for (tmp = 0; tmp < nr_channels; tmp++)
+ pdata->multi_block[tmp] = mb[tmp];
+ } else {
+ for (tmp = 0; tmp < nr_channels; tmp++)
+ pdata->multi_block[tmp] = 1;
+ }
+
return pdata;
}
#else
diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h
index f65dd104479f..4e0128c62704 100644
--- a/drivers/dma/dw/regs.h
+++ b/drivers/dma/dw/regs.h
@@ -12,7 +12,8 @@
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
-#define DW_DMA_MAX_NR_CHANNELS 8
+#include "internal.h"
+
#define DW_DMA_MAX_NR_REQUESTS 16
/* flow controller */
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 77242b37ef87..3879f80a4815 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -2451,6 +2451,9 @@ static int edma_pm_resume(struct device *dev)
int i;
s8 (*queue_priority_mapping)[2];
+ /* re initialize dummy slot to dummy param set */
+ edma_write_slot(ecc, ecc->dummy_slot, &dummy_paramset);
+
queue_priority_mapping = ecc->info->queue_priority_mapping;
/* Event queue priority mapping */
diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index db2f9e1653a2..90d29f90acfb 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -881,6 +881,7 @@ static struct of_device_id fsl_re_ids[] = {
{ .compatible = "fsl,raideng-v1.0", },
{}
};
+MODULE_DEVICE_TABLE(of, fsl_re_ids);
static struct platform_driver fsl_re_driver = {
.driver = {
diff --git a/drivers/dma/hsu/pci.c b/drivers/dma/hsu/pci.c
index b51639f045ed..4875fa428e81 100644
--- a/drivers/dma/hsu/pci.c
+++ b/drivers/dma/hsu/pci.c
@@ -77,13 +77,15 @@ static int hsu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (!chip)
return -ENOMEM;
+ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+ return ret;
+
chip->dev = &pdev->dev;
chip->regs = pcim_iomap_table(pdev)[0];
chip->length = pci_resource_len(pdev, 0);
chip->offset = HSU_PCI_CHAN_OFFSET;
- chip->irq = pdev->irq;
-
- pci_enable_msi(pdev);
+ chip->irq = pci_irq_vector(pdev, 0);
ret = hsu_dma_probe(chip);
if (ret)
diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
index 624f1e1e9c55..54db1411ce73 100644
--- a/drivers/dma/img-mdc-dma.c
+++ b/drivers/dma/img-mdc-dma.c
@@ -292,7 +292,7 @@ static struct dma_async_tx_descriptor *mdc_prep_dma_memcpy(
struct mdc_dma *mdma = mchan->mdma;
struct mdc_tx_desc *mdesc;
struct mdc_hw_list_desc *curr, *prev = NULL;
- dma_addr_t curr_phys, prev_phys;
+ dma_addr_t curr_phys;
if (!len)
return NULL;
@@ -324,7 +324,6 @@ static struct dma_async_tx_descriptor *mdc_prep_dma_memcpy(
xfer_size);
prev = curr;
- prev_phys = curr_phys;
mdesc->list_len++;
src += xfer_size;
@@ -375,7 +374,7 @@ static struct dma_async_tx_descriptor *mdc_prep_dma_cyclic(
struct mdc_dma *mdma = mchan->mdma;
struct mdc_tx_desc *mdesc;
struct mdc_hw_list_desc *curr, *prev = NULL;
- dma_addr_t curr_phys, prev_phys;
+ dma_addr_t curr_phys;
if (!buf_len && !period_len)
return NULL;
@@ -430,7 +429,6 @@ static struct dma_async_tx_descriptor *mdc_prep_dma_cyclic(
}
prev = curr;
- prev_phys = curr_phys;
mdesc->list_len++;
buf_addr += xfer_size;
@@ -458,7 +456,7 @@ static struct dma_async_tx_descriptor *mdc_prep_slave_sg(
struct mdc_tx_desc *mdesc;
struct scatterlist *sg;
struct mdc_hw_list_desc *curr, *prev = NULL;
- dma_addr_t curr_phys, prev_phys;
+ dma_addr_t curr_phys;
unsigned int i;
if (!sgl)
@@ -509,7 +507,6 @@ static struct dma_async_tx_descriptor *mdc_prep_slave_sg(
}
prev = curr;
- prev_phys = curr_phys;
mdesc->list_len++;
mdesc->list_xfer_size += xfer_size;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index b9629b2bfc05..d1651a50c349 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -298,6 +298,7 @@ struct sdma_engine;
* @event_id1 for channels that use 2 events
* @word_size peripheral access size
* @buf_tail ID of the buffer that was processed
+ * @buf_ptail ID of the previous buffer that was processed
* @num_bd max NUM_BD. number of descriptors currently handling
*/
struct sdma_channel {
@@ -309,6 +310,7 @@ struct sdma_channel {
unsigned int event_id1;
enum dma_slave_buswidth word_size;
unsigned int buf_tail;
+ unsigned int buf_ptail;
unsigned int num_bd;
unsigned int period_len;
struct sdma_buffer_descriptor *bd;
@@ -700,6 +702,8 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
sdmac->chn_real_count = bd->mode.count;
bd->mode.status |= BD_DONE;
bd->mode.count = sdmac->period_len;
+ sdmac->buf_ptail = sdmac->buf_tail;
+ sdmac->buf_tail = (sdmac->buf_tail + 1) % sdmac->num_bd;
/*
* The callback is called from the interrupt context in order
@@ -710,9 +714,6 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
- sdmac->buf_tail++;
- sdmac->buf_tail %= sdmac->num_bd;
-
if (error)
sdmac->status = old_status;
}
@@ -1186,6 +1187,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
sdmac->flags = 0;
sdmac->buf_tail = 0;
+ sdmac->buf_ptail = 0;
+ sdmac->chn_real_count = 0;
dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
sg_len, channel);
@@ -1288,6 +1291,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
sdmac->status = DMA_IN_PROGRESS;
sdmac->buf_tail = 0;
+ sdmac->buf_ptail = 0;
+ sdmac->chn_real_count = 0;
sdmac->period_len = period_len;
sdmac->flags |= IMX_DMA_SG_LOOP;
@@ -1385,7 +1390,7 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
u32 residue;
if (sdmac->flags & IMX_DMA_SG_LOOP)
- residue = (sdmac->num_bd - sdmac->buf_tail) *
+ residue = (sdmac->num_bd - sdmac->buf_ptail) *
sdmac->period_len - sdmac->chn_real_count;
else
residue = sdmac->chn_count - sdmac->chn_real_count;
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 49386ce04bf5..a371b07a0981 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -39,6 +39,7 @@
#include "../dmaengine.h"
static char *chanerr_str[] = {
+ "DMA Transfer Source Address Error",
"DMA Transfer Destination Address Error",
"Next Descriptor Address Error",
"Descriptor Error",
@@ -66,7 +67,6 @@ static char *chanerr_str[] = {
"Result Guard Tag verification Error",
"Result Application Tag verification Error",
"Result Reference Tag verification Error",
- NULL
};
static void ioat_eh(struct ioatdma_chan *ioat_chan);
@@ -75,13 +75,10 @@ static void ioat_print_chanerrs(struct ioatdma_chan *ioat_chan, u32 chanerr)
{
int i;
- for (i = 0; i < 32; i++) {
+ for (i = 0; i < ARRAY_SIZE(chanerr_str); i++) {
if ((chanerr >> i) & 1) {
- if (chanerr_str[i]) {
- dev_err(to_dev(ioat_chan), "Err(%d): %s\n",
- i, chanerr_str[i]);
- } else
- break;
+ dev_err(to_dev(ioat_chan), "Err(%d): %s\n",
+ i, chanerr_str[i]);
}
}
}
@@ -341,15 +338,12 @@ ioat_alloc_ring_ent(struct dma_chan *chan, int idx, gfp_t flags)
{
struct ioat_dma_descriptor *hw;
struct ioat_ring_ent *desc;
- struct ioatdma_device *ioat_dma;
struct ioatdma_chan *ioat_chan = to_ioat_chan(chan);
int chunk;
dma_addr_t phys;
u8 *pos;
off_t offs;
- ioat_dma = to_ioatdma_device(chan->device);
-
chunk = idx / IOAT_DESCS_PER_2M;
idx &= (IOAT_DESCS_PER_2M - 1);
offs = idx * IOAT_DESC_SZ;
@@ -614,11 +608,8 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)
tx = &desc->txd;
if (tx->cookie) {
- struct dmaengine_result res;
-
dma_cookie_complete(tx);
dma_descriptor_unmap(tx);
- res.result = DMA_TRANS_NOERROR;
dmaengine_desc_get_callback_invoke(tx, NULL);
tx->callback = NULL;
tx->callback_result = NULL;
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c
index 015f7110b96d..90eddd9f07e4 100644
--- a/drivers/dma/ioat/init.c
+++ b/drivers/dma/ioat/init.c
@@ -340,11 +340,13 @@ static int ioat_dma_self_test(struct ioatdma_device *ioat_dma)
dma_src = dma_map_single(dev, src, IOAT_TEST_SIZE, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_src)) {
dev_err(dev, "mapping src buffer failed\n");
+ err = -ENOMEM;
goto free_resources;
}
dma_dest = dma_map_single(dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE);
if (dma_mapping_error(dev, dma_dest)) {
dev_err(dev, "mapping dest buffer failed\n");
+ err = -ENOMEM;
goto unmap_src;
}
flags = DMA_PREP_INTERRUPT;
@@ -827,16 +829,20 @@ static int ioat_xor_val_self_test(struct ioatdma_device *ioat_dma)
op = IOAT_OP_XOR;
dest_dma = dma_map_page(dev, dest, 0, PAGE_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(dev, dest_dma))
+ if (dma_mapping_error(dev, dest_dma)) {
+ err = -ENOMEM;
goto free_resources;
+ }
for (i = 0; i < IOAT_NUM_SRC_TEST; i++)
dma_srcs[i] = DMA_ERROR_CODE;
for (i = 0; i < IOAT_NUM_SRC_TEST; i++) {
dma_srcs[i] = dma_map_page(dev, xor_srcs[i], 0, PAGE_SIZE,
DMA_TO_DEVICE);
- if (dma_mapping_error(dev, dma_srcs[i]))
+ if (dma_mapping_error(dev, dma_srcs[i])) {
+ err = -ENOMEM;
goto dma_unmap;
+ }
}
tx = dma->device_prep_dma_xor(dma_chan, dest_dma, dma_srcs,
IOAT_NUM_SRC_TEST, PAGE_SIZE,
@@ -904,8 +910,10 @@ static int ioat_xor_val_self_test(struct ioatdma_device *ioat_dma)
for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++) {
dma_srcs[i] = dma_map_page(dev, xor_val_srcs[i], 0, PAGE_SIZE,
DMA_TO_DEVICE);
- if (dma_mapping_error(dev, dma_srcs[i]))
+ if (dma_mapping_error(dev, dma_srcs[i])) {
+ err = -ENOMEM;
goto dma_unmap;
+ }
}
tx = dma->device_prep_dma_xor_val(dma_chan, dma_srcs,
IOAT_NUM_SRC_TEST + 1, PAGE_SIZE,
@@ -957,8 +965,10 @@ static int ioat_xor_val_self_test(struct ioatdma_device *ioat_dma)
for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++) {
dma_srcs[i] = dma_map_page(dev, xor_val_srcs[i], 0, PAGE_SIZE,
DMA_TO_DEVICE);
- if (dma_mapping_error(dev, dma_srcs[i]))
+ if (dma_mapping_error(dev, dma_srcs[i])) {
+ err = -ENOMEM;
goto dma_unmap;
+ }
}
tx = dma->device_prep_dma_xor_val(dma_chan, dma_srcs,
IOAT_NUM_SRC_TEST + 1, PAGE_SIZE,
@@ -1071,7 +1081,6 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca)
struct dma_device *dma;
struct dma_chan *c;
struct ioatdma_chan *ioat_chan;
- bool is_raid_device = false;
int err;
u16 val16;
@@ -1095,7 +1104,6 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca)
ioat_dma->cap &= ~(IOAT_CAP_XOR|IOAT_CAP_PQ);
if (ioat_dma->cap & IOAT_CAP_XOR) {
- is_raid_device = true;
dma->max_xor = 8;
dma_cap_set(DMA_XOR, dma->cap_mask);
@@ -1106,7 +1114,6 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca)
}
if (ioat_dma->cap & IOAT_CAP_PQ) {
- is_raid_device = true;
dma->device_prep_dma_pq = ioat_prep_pq;
dma->device_prep_dma_pq_val = ioat_prep_pq_val;
diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
index aabcb7934b05..01e25c68dd5a 100644
--- a/drivers/dma/k3dma.c
+++ b/drivers/dma/k3dma.c
@@ -458,13 +458,12 @@ static struct k3_dma_desc_sw *k3_dma_alloc_desc_resource(int num,
if (!ds)
return NULL;
- ds->desc_hw = dma_pool_alloc(d->pool, GFP_NOWAIT, &ds->desc_hw_lli);
+ ds->desc_hw = dma_pool_zalloc(d->pool, GFP_NOWAIT, &ds->desc_hw_lli);
if (!ds->desc_hw) {
dev_dbg(chan->device->dev, "vch %p: dma alloc fail\n", &c->vc);
kfree(ds);
return NULL;
}
- memset(ds->desc_hw, 0, sizeof(struct k3_desc_hw) * num);
ds->desc_num = num;
return ds;
}
diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c
index 818255844a3c..5ba5714d0b7c 100644
--- a/drivers/dma/mic_x100_dma.c
+++ b/drivers/dma/mic_x100_dma.c
@@ -554,9 +554,7 @@ static int mic_dma_init(struct mic_dma_device *mic_dma_dev,
int ret;
for (i = first_chan; i < first_chan + MIC_DMA_NUM_CHAN; i++) {
- unsigned long data;
ch = &mic_dma_dev->mic_ch[i];
- data = (unsigned long)ch;
ch->ch_num = i;
ch->owner = owner;
spin_lock_init(&ch->cleanup_lock);
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 23f75285a4d9..0cb951b743a6 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -68,6 +68,36 @@ static void mv_desc_init(struct mv_xor_desc_slot *desc,
hw_desc->byte_count = byte_count;
}
+/* Populate the descriptor */
+static void mv_xor_config_sg_ll_desc(struct mv_xor_desc_slot *desc,
+ dma_addr_t dma_src, dma_addr_t dma_dst,
+ u32 len, struct mv_xor_desc_slot *prev)
+{
+ struct mv_xor_desc *hw_desc = desc->hw_desc;
+
+ hw_desc->status = XOR_DESC_DMA_OWNED;
+ hw_desc->phy_next_desc = 0;
+ /* Configure for XOR with only one src address -> MEMCPY */
+ hw_desc->desc_command = XOR_DESC_OPERATION_XOR | (0x1 << 0);
+ hw_desc->phy_dest_addr = dma_dst;
+ hw_desc->phy_src_addr[0] = dma_src;
+ hw_desc->byte_count = len;
+
+ if (prev) {
+ struct mv_xor_desc *hw_prev = prev->hw_desc;
+
+ hw_prev->phy_next_desc = desc->async_tx.phys;
+ }
+}
+
+static void mv_xor_desc_config_eod(struct mv_xor_desc_slot *desc)
+{
+ struct mv_xor_desc *hw_desc = desc->hw_desc;
+
+ /* Enable end-of-descriptor interrupt */
+ hw_desc->desc_command |= XOR_DESC_EOD_INT_EN;
+}
+
static void mv_desc_set_mode(struct mv_xor_desc_slot *desc)
{
struct mv_xor_desc *hw_desc = desc->hw_desc;
@@ -228,8 +258,13 @@ mv_chan_clean_completed_slots(struct mv_xor_chan *mv_chan)
list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots,
node) {
- if (async_tx_test_ack(&iter->async_tx))
+ if (async_tx_test_ack(&iter->async_tx)) {
list_move_tail(&iter->node, &mv_chan->free_slots);
+ if (!list_empty(&iter->sg_tx_list)) {
+ list_splice_tail_init(&iter->sg_tx_list,
+ &mv_chan->free_slots);
+ }
+ }
}
return 0;
}
@@ -244,11 +279,20 @@ mv_desc_clean_slot(struct mv_xor_desc_slot *desc,
/* the client is allowed to attach dependent operations
* until 'ack' is set
*/
- if (!async_tx_test_ack(&desc->async_tx))
+ if (!async_tx_test_ack(&desc->async_tx)) {
/* move this slot to the completed_slots */
list_move_tail(&desc->node, &mv_chan->completed_slots);
- else
+ if (!list_empty(&desc->sg_tx_list)) {
+ list_splice_tail_init(&desc->sg_tx_list,
+ &mv_chan->completed_slots);
+ }
+ } else {
list_move_tail(&desc->node, &mv_chan->free_slots);
+ if (!list_empty(&desc->sg_tx_list)) {
+ list_splice_tail_init(&desc->sg_tx_list,
+ &mv_chan->free_slots);
+ }
+ }
return 0;
}
@@ -450,6 +494,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
dma_async_tx_descriptor_init(&slot->async_tx, chan);
slot->async_tx.tx_submit = mv_xor_tx_submit;
INIT_LIST_HEAD(&slot->node);
+ INIT_LIST_HEAD(&slot->sg_tx_list);
dma_desc = mv_chan->dma_desc_pool;
slot->async_tx.phys = dma_desc + idx * MV_XOR_SLOT_SIZE;
slot->idx = idx++;
@@ -617,6 +662,132 @@ mv_xor_prep_dma_interrupt(struct dma_chan *chan, unsigned long flags)
return mv_xor_prep_dma_xor(chan, dest, &src, 1, len, flags);
}
+/**
+ * mv_xor_prep_dma_sg - prepare descriptors for a memory sg transaction
+ * @chan: DMA channel
+ * @dst_sg: Destination scatter list
+ * @dst_sg_len: Number of entries in destination scatter list
+ * @src_sg: Source scatter list
+ * @src_sg_len: Number of entries in source scatter list
+ * @flags: transfer ack flags
+ *
+ * Return: Async transaction descriptor on success and NULL on failure
+ */
+static struct dma_async_tx_descriptor *
+mv_xor_prep_dma_sg(struct dma_chan *chan, struct scatterlist *dst_sg,
+ unsigned int dst_sg_len, struct scatterlist *src_sg,
+ unsigned int src_sg_len, unsigned long flags)
+{
+ struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+ struct mv_xor_desc_slot *new;
+ struct mv_xor_desc_slot *first = NULL;
+ struct mv_xor_desc_slot *prev = NULL;
+ size_t len, dst_avail, src_avail;
+ dma_addr_t dma_dst, dma_src;
+ int desc_cnt = 0;
+ int ret;
+
+ dev_dbg(mv_chan_to_devp(mv_chan),
+ "%s dst_sg_len: %d src_sg_len: %d flags: %ld\n",
+ __func__, dst_sg_len, src_sg_len, flags);
+
+ dst_avail = sg_dma_len(dst_sg);
+ src_avail = sg_dma_len(src_sg);
+
+ /* Run until we are out of scatterlist entries */
+ while (true) {
+ /* Allocate and populate the descriptor */
+ desc_cnt++;
+ new = mv_chan_alloc_slot(mv_chan);
+ if (!new) {
+ dev_err(mv_chan_to_devp(mv_chan),
+ "Out of descriptors (desc_cnt=%d)!\n",
+ desc_cnt);
+ goto err;
+ }
+
+ len = min_t(size_t, src_avail, dst_avail);
+ len = min_t(size_t, len, MV_XOR_MAX_BYTE_COUNT);
+ if (len == 0)
+ goto fetch;
+
+ if (len < MV_XOR_MIN_BYTE_COUNT) {
+ dev_err(mv_chan_to_devp(mv_chan),
+ "Transfer size of %zu too small!\n", len);
+ goto err;
+ }
+
+ dma_dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) -
+ dst_avail;
+ dma_src = sg_dma_address(src_sg) + sg_dma_len(src_sg) -
+ src_avail;
+
+ /* Check if a new window needs to get added for 'dst' */
+ ret = mv_xor_add_io_win(mv_chan, dma_dst);
+ if (ret)
+ goto err;
+
+ /* Check if a new window needs to get added for 'src' */
+ ret = mv_xor_add_io_win(mv_chan, dma_src);
+ if (ret)
+ goto err;
+
+ /* Populate the descriptor */
+ mv_xor_config_sg_ll_desc(new, dma_src, dma_dst, len, prev);
+ prev = new;
+ dst_avail -= len;
+ src_avail -= len;
+
+ if (!first)
+ first = new;
+ else
+ list_move_tail(&new->node, &first->sg_tx_list);
+
+fetch:
+ /* Fetch the next dst scatterlist entry */
+ if (dst_avail == 0) {
+ if (dst_sg_len == 0)
+ break;
+
+ /* Fetch the next entry: if there are no more: done */
+ dst_sg = sg_next(dst_sg);
+ if (dst_sg == NULL)
+ break;
+
+ dst_sg_len--;
+ dst_avail = sg_dma_len(dst_sg);
+ }
+
+ /* Fetch the next src scatterlist entry */
+ if (src_avail == 0) {
+ if (src_sg_len == 0)
+ break;
+
+ /* Fetch the next entry: if there are no more: done */
+ src_sg = sg_next(src_sg);
+ if (src_sg == NULL)
+ break;
+
+ src_sg_len--;
+ src_avail = sg_dma_len(src_sg);
+ }
+ }
+
+ /* Set the EOD flag in the last descriptor */
+ mv_xor_desc_config_eod(new);
+ first->async_tx.flags = flags;
+
+ return &first->async_tx;
+
+err:
+ /* Cleanup: Move all descriptors back into the free list */
+ spin_lock_bh(&mv_chan->lock);
+ mv_desc_clean_slot(first, mv_chan);
+ spin_unlock_bh(&mv_chan->lock);
+
+ return NULL;
+}
+
static void mv_xor_free_chan_resources(struct dma_chan *chan)
{
struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
@@ -1083,6 +1254,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
dma_dev->device_prep_dma_interrupt = mv_xor_prep_dma_interrupt;
if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask))
dma_dev->device_prep_dma_memcpy = mv_xor_prep_dma_memcpy;
+ if (dma_has_cap(DMA_SG, dma_dev->cap_mask))
+ dma_dev->device_prep_dma_sg = mv_xor_prep_dma_sg;
if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
dma_dev->max_xor = 8;
dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor;
@@ -1132,10 +1305,11 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
goto err_free_irq;
}
- dev_info(&pdev->dev, "Marvell XOR (%s): ( %s%s%s)\n",
+ dev_info(&pdev->dev, "Marvell XOR (%s): ( %s%s%s%s)\n",
mv_chan->op_in_desc ? "Descriptor Mode" : "Registers Mode",
dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
+ dma_has_cap(DMA_SG, dma_dev->cap_mask) ? "sg " : "",
dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
dma_async_device_register(dma_dev);
@@ -1378,6 +1552,7 @@ static int mv_xor_probe(struct platform_device *pdev)
dma_cap_zero(cap_mask);
dma_cap_set(DMA_MEMCPY, cap_mask);
+ dma_cap_set(DMA_SG, cap_mask);
dma_cap_set(DMA_XOR, cap_mask);
dma_cap_set(DMA_INTERRUPT, cap_mask);
@@ -1455,12 +1630,7 @@ static struct platform_driver mv_xor_driver = {
},
};
-
-static int __init mv_xor_init(void)
-{
- return platform_driver_register(&mv_xor_driver);
-}
-device_initcall(mv_xor_init);
+builtin_platform_driver(mv_xor_driver);
/*
MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index 88eeab222a23..cf921dd6af73 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -148,6 +148,7 @@ struct mv_xor_chan {
*/
struct mv_xor_desc_slot {
struct list_head node;
+ struct list_head sg_tx_list;
enum dma_transaction_type type;
void *hw_desc;
u16 idx;
diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c
index 09de71519d37..3f45b9bdf201 100644
--- a/drivers/dma/nbpfaxi.c
+++ b/drivers/dma/nbpfaxi.c
@@ -225,6 +225,8 @@ struct nbpf_channel {
struct nbpf_device {
struct dma_device dma_dev;
void __iomem *base;
+ u32 max_burst_mem_read;
+ u32 max_burst_mem_write;
struct clk *clk;
const struct nbpf_config *config;
unsigned int eirq;
@@ -425,10 +427,33 @@ static void nbpf_chan_configure(struct nbpf_channel *chan)
nbpf_chan_write(chan, NBPF_CHAN_CFG, NBPF_CHAN_CFG_DMS | chan->dmarq_cfg);
}
-static u32 nbpf_xfer_ds(struct nbpf_device *nbpf, size_t size)
+static u32 nbpf_xfer_ds(struct nbpf_device *nbpf, size_t size,
+ enum dma_transfer_direction direction)
{
+ int max_burst = nbpf->config->buffer_size * 8;
+
+ if (nbpf->max_burst_mem_read || nbpf->max_burst_mem_write) {
+ switch (direction) {
+ case DMA_MEM_TO_MEM:
+ max_burst = min_not_zero(nbpf->max_burst_mem_read,
+ nbpf->max_burst_mem_write);
+ break;
+ case DMA_MEM_TO_DEV:
+ if (nbpf->max_burst_mem_read)
+ max_burst = nbpf->max_burst_mem_read;
+ break;
+ case DMA_DEV_TO_MEM:
+ if (nbpf->max_burst_mem_write)
+ max_burst = nbpf->max_burst_mem_write;
+ break;
+ case DMA_DEV_TO_DEV:
+ default:
+ break;
+ }
+ }
+
/* Maximum supported bursts depend on the buffer size */
- return min_t(int, __ffs(size), ilog2(nbpf->config->buffer_size * 8));
+ return min_t(int, __ffs(size), ilog2(max_burst));
}
static size_t nbpf_xfer_size(struct nbpf_device *nbpf,
@@ -458,7 +483,7 @@ static size_t nbpf_xfer_size(struct nbpf_device *nbpf,
size = burst;
}
- return nbpf_xfer_ds(nbpf, size);
+ return nbpf_xfer_ds(nbpf, size, DMA_TRANS_NONE);
}
/*
@@ -507,7 +532,7 @@ static int nbpf_prep_one(struct nbpf_link_desc *ldesc,
* transfers we enable the SBE bit and terminate the transfer in our
* .device_pause handler.
*/
- mem_xfer = nbpf_xfer_ds(chan->nbpf, size);
+ mem_xfer = nbpf_xfer_ds(chan->nbpf, size, direction);
switch (direction) {
case DMA_DEV_TO_MEM:
@@ -1313,6 +1338,11 @@ static int nbpf_probe(struct platform_device *pdev)
if (IS_ERR(nbpf->clk))
return PTR_ERR(nbpf->clk);
+ of_property_read_u32(np, "max-burst-mem-read",
+ &nbpf->max_burst_mem_read);
+ of_property_read_u32(np, "max-burst-mem-write",
+ &nbpf->max_burst_mem_write);
+
nbpf->config = cfg;
for (i = 0; irqs < ARRAY_SIZE(irqbuf); i++) {
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 7ca27d4b1c54..ac68666cd3f4 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -166,6 +166,9 @@ enum {
CSDP_DST_BURST_16 = 1 << 14,
CSDP_DST_BURST_32 = 2 << 14,
CSDP_DST_BURST_64 = 3 << 14,
+ CSDP_WRITE_NON_POSTED = 0 << 16,
+ CSDP_WRITE_POSTED = 1 << 16,
+ CSDP_WRITE_LAST_NON_POSTED = 2 << 16,
CICR_TOUT_IE = BIT(0), /* OMAP1 only */
CICR_DROP_IE = BIT(1),
@@ -422,7 +425,30 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
c->running = true;
}
-static void omap_dma_stop(struct omap_chan *c)
+static void omap_dma_drain_chan(struct omap_chan *c)
+{
+ int i;
+ u32 val;
+
+ /* Wait for sDMA FIFO to drain */
+ for (i = 0; ; i++) {
+ val = omap_dma_chan_read(c, CCR);
+ if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
+ break;
+
+ if (i > 100)
+ break;
+
+ udelay(5);
+ }
+
+ if (val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
+ dev_err(c->vc.chan.device->dev,
+ "DMA drain did not complete on lch %d\n",
+ c->dma_ch);
+}
+
+static int omap_dma_stop(struct omap_chan *c)
{
struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
uint32_t val;
@@ -435,7 +461,6 @@ static void omap_dma_stop(struct omap_chan *c)
val = omap_dma_chan_read(c, CCR);
if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) {
uint32_t sysconfig;
- unsigned i;
sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
val = sysconfig & ~DMA_SYSCONFIG_MIDLEMODE_MASK;
@@ -446,27 +471,19 @@ static void omap_dma_stop(struct omap_chan *c)
val &= ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
- /* Wait for sDMA FIFO to drain */
- for (i = 0; ; i++) {
- val = omap_dma_chan_read(c, CCR);
- if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
- break;
-
- if (i > 100)
- break;
-
- udelay(5);
- }
-
- if (val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
- dev_err(c->vc.chan.device->dev,
- "DMA drain did not complete on lch %d\n",
- c->dma_ch);
+ if (!(c->ccr & CCR_BUFFERING_DISABLE))
+ omap_dma_drain_chan(c);
omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else {
+ if (!(val & CCR_ENABLE))
+ return -EINVAL;
+
val &= ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
+
+ if (!(c->ccr & CCR_BUFFERING_DISABLE))
+ omap_dma_drain_chan(c);
}
mb();
@@ -481,8 +498,8 @@ static void omap_dma_stop(struct omap_chan *c)
omap_dma_chan_write(c, CLNK_CTRL, val);
}
-
c->running = false;
+ return 0;
}
static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d)
@@ -836,6 +853,8 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
} else {
txstate->residue = 0;
}
+ if (ret == DMA_IN_PROGRESS && c->paused)
+ ret = DMA_PAUSED;
spin_unlock_irqrestore(&c->vc.lock, flags);
return ret;
@@ -865,15 +884,18 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
unsigned i, es, en, frame_bytes;
bool ll_failed = false;
u32 burst;
+ u32 port_window, port_window_bytes;
if (dir == DMA_DEV_TO_MEM) {
dev_addr = c->cfg.src_addr;
dev_width = c->cfg.src_addr_width;
burst = c->cfg.src_maxburst;
+ port_window = c->cfg.src_port_window_size;
} else if (dir == DMA_MEM_TO_DEV) {
dev_addr = c->cfg.dst_addr;
dev_width = c->cfg.dst_addr_width;
burst = c->cfg.dst_maxburst;
+ port_window = c->cfg.dst_port_window_size;
} else {
dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
return NULL;
@@ -894,6 +916,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
return NULL;
}
+ /* When the port_window is used, one frame must cover the window */
+ if (port_window) {
+ burst = port_window;
+ port_window_bytes = port_window * es_bytes[es];
+ }
+
/* Now allocate and setup the descriptor. */
d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
if (!d)
@@ -905,11 +933,45 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->ccr = c->ccr | CCR_SYNC_FRAME;
if (dir == DMA_DEV_TO_MEM) {
- d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
+
+ d->ccr |= CCR_DST_AMODE_POSTINC;
+ if (port_window) {
+ d->ccr |= CCR_SRC_AMODE_DBLIDX;
+ d->ei = 1;
+ /*
+ * One frame covers the port_window and by configure
+ * the source frame index to be -1 * (port_window - 1)
+ * we instruct the sDMA that after a frame is processed
+ * it should move back to the start of the window.
+ */
+ d->fi = -(port_window_bytes - 1);
+
+ if (port_window_bytes >= 64)
+ d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED;
+ else if (port_window_bytes >= 32)
+ d->csdp = CSDP_SRC_BURST_32 | CSDP_SRC_PACKED;
+ else if (port_window_bytes >= 16)
+ d->csdp = CSDP_SRC_BURST_16 | CSDP_SRC_PACKED;
+ } else {
+ d->ccr |= CCR_SRC_AMODE_CONSTANT;
+ }
} else {
- d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC;
d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED;
+
+ d->ccr |= CCR_SRC_AMODE_POSTINC;
+ if (port_window) {
+ d->ccr |= CCR_DST_AMODE_DBLIDX;
+
+ if (port_window_bytes >= 64)
+ d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
+ else if (port_window_bytes >= 32)
+ d->csdp = CSDP_DST_BURST_32 | CSDP_DST_PACKED;
+ else if (port_window_bytes >= 16)
+ d->csdp = CSDP_DST_BURST_16 | CSDP_DST_PACKED;
+ } else {
+ d->ccr |= CCR_DST_AMODE_CONSTANT;
+ }
}
d->cicr = CICR_DROP_IE | CICR_BLOCK_IE;
@@ -927,6 +989,9 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
d->ccr |= CCR_TRIGGER_SRC;
d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
+
+ if (port_window)
+ d->csdp |= CSDP_WRITE_LAST_NON_POSTED;
}
if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
d->clnk_ctrl = c->dma_ch;
@@ -952,6 +1017,16 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
osg->addr = sg_dma_address(sgent);
osg->en = en;
osg->fn = sg_dma_len(sgent) / frame_bytes;
+ if (port_window && dir == DMA_MEM_TO_DEV) {
+ osg->ei = 1;
+ /*
+ * One frame covers the port_window and by configure
+ * the source frame index to be -1 * (port_window - 1)
+ * we instruct the sDMA that after a frame is processed
+ * it should move back to the start of the window.
+ */
+ osg->fi = -(port_window_bytes - 1);
+ }
if (d->using_ll) {
osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,
@@ -1247,10 +1322,8 @@ static int omap_dma_terminate_all(struct dma_chan *chan)
omap_dma_stop(c);
}
- if (c->cyclic) {
- c->cyclic = false;
- c->paused = false;
- }
+ c->cyclic = false;
+ c->paused = false;
vchan_get_all_descriptors(&c->vc, &head);
spin_unlock_irqrestore(&c->vc.lock, flags);
@@ -1269,28 +1342,66 @@ static void omap_dma_synchronize(struct dma_chan *chan)
static int omap_dma_pause(struct dma_chan *chan)
{
struct omap_chan *c = to_omap_dma_chan(chan);
+ struct omap_dmadev *od = to_omap_dma_dev(chan->device);
+ unsigned long flags;
+ int ret = -EINVAL;
+ bool can_pause = false;
- /* Pause/Resume only allowed with cyclic mode */
- if (!c->cyclic)
- return -EINVAL;
+ spin_lock_irqsave(&od->irq_lock, flags);
- if (!c->paused) {
- omap_dma_stop(c);
- c->paused = true;
+ if (!c->desc)
+ goto out;
+
+ if (c->cyclic)
+ can_pause = true;
+
+ /*
+ * We do not allow DMA_MEM_TO_DEV transfers to be paused.
+ * From the AM572x TRM, 16.1.4.18 Disabling a Channel During Transfer:
+ * "When a channel is disabled during a transfer, the channel undergoes
+ * an abort, unless it is hardware-source-synchronized …".
+ * A source-synchronised channel is one where the fetching of data is
+ * under control of the device. In other words, a device-to-memory
+ * transfer. So, a destination-synchronised channel (which would be a
+ * memory-to-device transfer) undergoes an abort if the the CCR_ENABLE
+ * bit is cleared.
+ * From 16.1.4.20.4.6.2 Abort: "If an abort trigger occurs, the channel
+ * aborts immediately after completion of current read/write
+ * transactions and then the FIFO is cleaned up." The term "cleaned up"
+ * is not defined. TI recommends to check that RD_ACTIVE and WR_ACTIVE
+ * are both clear _before_ disabling the channel, otherwise data loss
+ * will occur.
+ * The problem is that if the channel is active, then device activity
+ * can result in DMA activity starting between reading those as both
+ * clear and the write to DMA_CCR to clear the enable bit hitting the
+ * hardware. If the DMA hardware can't drain the data in its FIFO to the
+ * destination, then data loss "might" occur (say if we write to an UART
+ * and the UART is not accepting any further data).
+ */
+ else if (c->desc->dir == DMA_DEV_TO_MEM)
+ can_pause = true;
+
+ if (can_pause && !c->paused) {
+ ret = omap_dma_stop(c);
+ if (!ret)
+ c->paused = true;
}
+out:
+ spin_unlock_irqrestore(&od->irq_lock, flags);
- return 0;
+ return ret;
}
static int omap_dma_resume(struct dma_chan *chan)
{
struct omap_chan *c = to_omap_dma_chan(chan);
+ struct omap_dmadev *od = to_omap_dma_dev(chan->device);
+ unsigned long flags;
+ int ret = -EINVAL;
- /* Pause/Resume only allowed with cyclic mode */
- if (!c->cyclic)
- return -EINVAL;
+ spin_lock_irqsave(&od->irq_lock, flags);
- if (c->paused) {
+ if (c->paused && c->desc) {
mb();
/* Restore channel link register */
@@ -1298,9 +1409,11 @@ static int omap_dma_resume(struct dma_chan *chan)
omap_dma_start(c, c->desc);
c->paused = false;
+ ret = 0;
}
+ spin_unlock_irqrestore(&od->irq_lock, flags);
- return 0;
+ return ret;
}
static int omap_dma_chan_init(struct omap_dmadev *od)
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index df95727dc2fb..f9028e9d0dfc 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -417,10 +417,8 @@ static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd)
{
struct pch_dma_desc *desc = to_pd_desc(txd);
struct pch_dma_chan *pd_chan = to_pd_chan(txd->chan);
- dma_cookie_t cookie;
spin_lock(&pd_chan->lock);
- cookie = dma_cookie_assign(txd);
if (list_empty(&pd_chan->active_list)) {
list_add_tail(&desc->desc_node, &pd_chan->active_list);
@@ -439,9 +437,8 @@ static struct pch_dma_desc *pdc_alloc_desc(struct dma_chan *chan, gfp_t flags)
struct pch_dma *pd = to_pd(chan->device);
dma_addr_t addr;
- desc = pci_pool_alloc(pd->pool, flags, &addr);
+ desc = pci_pool_zalloc(pd->pool, flags, &addr);
if (desc) {
- memset(desc, 0, sizeof(struct pch_dma_desc));
INIT_LIST_HEAD(&desc->tx_list);
dma_async_tx_descriptor_init(&desc->txd, chan);
desc->txd.tx_submit = pd_tx_submit;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 030fe05ed43b..87fd01539fcb 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -570,7 +570,8 @@ static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
buf[0] = CMD_DMAADDH;
buf[0] |= (da << 1);
- *((__le16 *)&buf[1]) = cpu_to_le16(val);
+ buf[1] = val;
+ buf[2] = val >> 8;
PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n",
da == 1 ? "DA" : "SA", val);
@@ -724,7 +725,10 @@ static inline u32 _emit_MOV(unsigned dry_run, u8 buf[],
buf[0] = CMD_DMAMOV;
buf[1] = dst;
- *((__le32 *)&buf[2]) = cpu_to_le32(val);
+ buf[2] = val;
+ buf[3] = val >> 8;
+ buf[4] = val >> 16;
+ buf[5] = val >> 24;
PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n",
dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val);
@@ -899,10 +903,11 @@ static inline u32 _emit_GO(unsigned dry_run, u8 buf[],
buf[0] = CMD_DMAGO;
buf[0] |= (ns << 1);
-
buf[1] = chan & 0x7;
-
- *((__le32 *)&buf[2]) = cpu_to_le32(addr);
+ buf[2] = addr;
+ buf[3] = addr >> 8;
+ buf[4] = addr >> 16;
+ buf[5] = addr >> 24;
return SZ_DMAGO;
}
@@ -1883,11 +1888,8 @@ static int dmac_alloc_resources(struct pl330_dmac *pl330)
static int pl330_add(struct pl330_dmac *pl330)
{
- void __iomem *regs;
int i, ret;
- regs = pl330->base;
-
/* Check if we can handle this DMAC */
if ((pl330->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) {
dev_err(pl330->ddma.dev, "PERIPH_ID 0x%x !\n",
@@ -2263,6 +2265,11 @@ static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch,
}
pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
pm_runtime_put_autosuspend(pl330->ddma.dev);
+
+ /* If DMAMOV hasn't finished yet, SAR/DAR can be zero */
+ if (!val)
+ return 0;
+
return val - addr;
}
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index 3f56f9ca4482..b53fb618bbf6 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -413,15 +413,6 @@ static inline void pxad_init_debugfs(struct pxad_device *pdev) {}
static inline void pxad_cleanup_debugfs(struct pxad_device *pdev) {}
#endif
-/*
- * In the transition phase where legacy pxa handling is done at the same time as
- * mmp_dma, the DMA physical channel split between the 2 DMA providers is done
- * through legacy_reserved. Legacy code reserves DMA channels by settings
- * corresponding bits in legacy_reserved.
- */
-static u32 legacy_reserved;
-static u32 legacy_unavailable;
-
static struct pxad_phy *lookup_phy(struct pxad_chan *pchan)
{
int prio, i;
@@ -442,14 +433,10 @@ static struct pxad_phy *lookup_phy(struct pxad_chan *pchan)
for (i = 0; i < pdev->nr_chans; i++) {
if (prio != (i & 0xf) >> 2)
continue;
- if ((i < 32) && (legacy_reserved & BIT(i)))
- continue;
phy = &pdev->phys[i];
if (!phy->vchan) {
phy->vchan = pchan;
found = phy;
- if (i < 32)
- legacy_unavailable |= BIT(i);
goto out_unlock;
}
}
@@ -469,7 +456,6 @@ static void pxad_free_phy(struct pxad_chan *chan)
struct pxad_device *pdev = to_pxad_dev(chan->vc.chan.device);
unsigned long flags;
u32 reg;
- int i;
dev_dbg(&chan->vc.chan.dev->device,
"%s(): freeing\n", __func__);
@@ -483,9 +469,6 @@ static void pxad_free_phy(struct pxad_chan *chan)
}
spin_lock_irqsave(&pdev->phy_lock, flags);
- for (i = 0; i < 32; i++)
- if (chan->phy == &pdev->phys[i])
- legacy_unavailable &= ~BIT(i);
chan->phy->vchan = NULL;
chan->phy = NULL;
spin_unlock_irqrestore(&pdev->phy_lock, flags);
@@ -739,8 +722,6 @@ static irqreturn_t pxad_int_handler(int irq, void *dev_id)
i = __ffs(dint);
dint &= (dint - 1);
phy = &pdev->phys[i];
- if ((i < 32) && (legacy_reserved & BIT(i)))
- continue;
if (pxad_chan_handler(irq, phy) == IRQ_HANDLED)
ret = IRQ_HANDLED;
}
@@ -1522,15 +1503,6 @@ bool pxad_filter_fn(struct dma_chan *chan, void *param)
}
EXPORT_SYMBOL_GPL(pxad_filter_fn);
-int pxad_toggle_reserved_channel(int legacy_channel)
-{
- if (legacy_unavailable & (BIT(legacy_channel)))
- return -EBUSY;
- legacy_reserved ^= BIT(legacy_channel);
- return 0;
-}
-EXPORT_SYMBOL_GPL(pxad_toggle_reserved_channel);
-
module_platform_driver(pxad_driver);
MODULE_DESCRIPTION("Marvell PXA Peripheral DMA Driver");
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index e244e10a94b5..3c982c96b4b7 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -56,6 +56,7 @@
#include <linux/irq.h>
#include <linux/atomic.h>
#include <linux/pm_runtime.h>
+#include <linux/msi.h>
#include "../dmaengine.h"
#include "hidma.h"
@@ -70,6 +71,7 @@
#define HIDMA_ERR_INFO_SW 0xFF
#define HIDMA_ERR_CODE_UNEXPECTED_TERMINATE 0x0
#define HIDMA_NR_DEFAULT_DESC 10
+#define HIDMA_MSI_INTS 11
static inline struct hidma_dev *to_hidma_dev(struct dma_device *dmadev)
{
@@ -553,6 +555,17 @@ static irqreturn_t hidma_chirq_handler(int chirq, void *arg)
return hidma_ll_inthandler(chirq, lldev);
}
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+static irqreturn_t hidma_chirq_handler_msi(int chirq, void *arg)
+{
+ struct hidma_lldev **lldevp = arg;
+ struct hidma_dev *dmadev = to_hidma_dev_from_lldev(lldevp);
+
+ return hidma_ll_inthandler_msi(chirq, *lldevp,
+ 1 << (chirq - dmadev->msi_virqbase));
+}
+#endif
+
static ssize_t hidma_show_values(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -567,8 +580,13 @@ static ssize_t hidma_show_values(struct device *dev,
return strlen(buf);
}
-static int hidma_create_sysfs_entry(struct hidma_dev *dev, char *name,
- int mode)
+static inline void hidma_sysfs_uninit(struct hidma_dev *dev)
+{
+ device_remove_file(dev->ddev.dev, dev->chid_attrs);
+}
+
+static struct device_attribute*
+hidma_create_sysfs_entry(struct hidma_dev *dev, char *name, int mode)
{
struct device_attribute *attrs;
char *name_copy;
@@ -576,18 +594,125 @@ static int hidma_create_sysfs_entry(struct hidma_dev *dev, char *name,
attrs = devm_kmalloc(dev->ddev.dev, sizeof(struct device_attribute),
GFP_KERNEL);
if (!attrs)
- return -ENOMEM;
+ return NULL;
name_copy = devm_kstrdup(dev->ddev.dev, name, GFP_KERNEL);
if (!name_copy)
- return -ENOMEM;
+ return NULL;
attrs->attr.name = name_copy;
attrs->attr.mode = mode;
attrs->show = hidma_show_values;
sysfs_attr_init(&attrs->attr);
- return device_create_file(dev->ddev.dev, attrs);
+ return attrs;
+}
+
+static int hidma_sysfs_init(struct hidma_dev *dev)
+{
+ dev->chid_attrs = hidma_create_sysfs_entry(dev, "chid", S_IRUGO);
+ if (!dev->chid_attrs)
+ return -ENOMEM;
+
+ return device_create_file(dev->ddev.dev, dev->chid_attrs);
+}
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+static void hidma_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+ struct device *dev = msi_desc_to_dev(desc);
+ struct hidma_dev *dmadev = dev_get_drvdata(dev);
+
+ if (!desc->platform.msi_index) {
+ writel(msg->address_lo, dmadev->dev_evca + 0x118);
+ writel(msg->address_hi, dmadev->dev_evca + 0x11C);
+ writel(msg->data, dmadev->dev_evca + 0x120);
+ }
+}
+#endif
+
+static void hidma_free_msis(struct hidma_dev *dmadev)
+{
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+ struct device *dev = dmadev->ddev.dev;
+ struct msi_desc *desc;
+
+ /* free allocated MSI interrupts above */
+ for_each_msi_entry(desc, dev)
+ devm_free_irq(dev, desc->irq, &dmadev->lldev);
+
+ platform_msi_domain_free_irqs(dev);
+#endif
+}
+
+static int hidma_request_msi(struct hidma_dev *dmadev,
+ struct platform_device *pdev)
+{
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+ int rc;
+ struct msi_desc *desc;
+ struct msi_desc *failed_desc = NULL;
+
+ rc = platform_msi_domain_alloc_irqs(&pdev->dev, HIDMA_MSI_INTS,
+ hidma_write_msi_msg);
+ if (rc)
+ return rc;
+
+ for_each_msi_entry(desc, &pdev->dev) {
+ if (!desc->platform.msi_index)
+ dmadev->msi_virqbase = desc->irq;
+
+ rc = devm_request_irq(&pdev->dev, desc->irq,
+ hidma_chirq_handler_msi,
+ 0, "qcom-hidma-msi",
+ &dmadev->lldev);
+ if (rc) {
+ failed_desc = desc;
+ break;
+ }
+ }
+
+ if (rc) {
+ /* free allocated MSI interrupts above */
+ for_each_msi_entry(desc, &pdev->dev) {
+ if (desc == failed_desc)
+ break;
+ devm_free_irq(&pdev->dev, desc->irq,
+ &dmadev->lldev);
+ }
+ } else {
+ /* Add callback to free MSIs on teardown */
+ hidma_ll_setup_irq(dmadev->lldev, true);
+
+ }
+ if (rc)
+ dev_warn(&pdev->dev,
+ "failed to request MSI irq, falling back to wired IRQ\n");
+ return rc;
+#else
+ return -EINVAL;
+#endif
+}
+
+static bool hidma_msi_capable(struct device *dev)
+{
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+ const char *of_compat;
+ int ret = -EINVAL;
+
+ if (!adev || acpi_disabled) {
+ ret = device_property_read_string(dev, "compatible",
+ &of_compat);
+ if (ret)
+ return false;
+
+ ret = strcmp(of_compat, "qcom,hidma-1.1");
+ } else {
+#ifdef CONFIG_ACPI
+ ret = strcmp(acpi_device_hid(adev), "QCOM8062");
+#endif
+ }
+ return ret == 0;
}
static int hidma_probe(struct platform_device *pdev)
@@ -599,6 +724,7 @@ static int hidma_probe(struct platform_device *pdev)
void __iomem *evca;
void __iomem *trca;
int rc;
+ bool msi;
pm_runtime_set_autosuspend_delay(&pdev->dev, HIDMA_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
@@ -660,6 +786,12 @@ static int hidma_probe(struct platform_device *pdev)
dmadev->ddev.device_terminate_all = hidma_terminate_all;
dmadev->ddev.copy_align = 8;
+ /*
+ * Determine the MSI capability of the platform. Old HW doesn't
+ * support MSI.
+ */
+ msi = hidma_msi_capable(&pdev->dev);
+
device_property_read_u32(&pdev->dev, "desc-count",
&dmadev->nr_descriptors);
@@ -688,10 +820,17 @@ static int hidma_probe(struct platform_device *pdev)
goto dmafree;
}
- rc = devm_request_irq(&pdev->dev, chirq, hidma_chirq_handler, 0,
- "qcom-hidma", dmadev->lldev);
- if (rc)
- goto uninit;
+ platform_set_drvdata(pdev, dmadev);
+ if (msi)
+ rc = hidma_request_msi(dmadev, pdev);
+
+ if (!msi || rc) {
+ hidma_ll_setup_irq(dmadev->lldev, false);
+ rc = devm_request_irq(&pdev->dev, chirq, hidma_chirq_handler,
+ 0, "qcom-hidma", dmadev->lldev);
+ if (rc)
+ goto uninit;
+ }
INIT_LIST_HEAD(&dmadev->ddev.channels);
rc = hidma_chan_init(dmadev, 0);
@@ -705,14 +844,16 @@ static int hidma_probe(struct platform_device *pdev)
dmadev->irq = chirq;
tasklet_init(&dmadev->task, hidma_issue_task, (unsigned long)dmadev);
hidma_debug_init(dmadev);
- hidma_create_sysfs_entry(dmadev, "chid", S_IRUGO);
+ hidma_sysfs_init(dmadev);
dev_info(&pdev->dev, "HI-DMA engine driver registration complete\n");
- platform_set_drvdata(pdev, dmadev);
pm_runtime_mark_last_busy(dmadev->ddev.dev);
pm_runtime_put_autosuspend(dmadev->ddev.dev);
return 0;
uninit:
+ if (msi)
+ hidma_free_msis(dmadev);
+
hidma_debug_uninit(dmadev);
hidma_ll_uninit(dmadev->lldev);
dmafree:
@@ -730,8 +871,13 @@ static int hidma_remove(struct platform_device *pdev)
pm_runtime_get_sync(dmadev->ddev.dev);
dma_async_device_unregister(&dmadev->ddev);
- devm_free_irq(dmadev->ddev.dev, dmadev->irq, dmadev->lldev);
+ if (!dmadev->lldev->msi_support)
+ devm_free_irq(dmadev->ddev.dev, dmadev->irq, dmadev->lldev);
+ else
+ hidma_free_msis(dmadev);
+
tasklet_kill(&dmadev->task);
+ hidma_sysfs_uninit(dmadev);
hidma_debug_uninit(dmadev);
hidma_ll_uninit(dmadev->lldev);
hidma_free(dmadev);
@@ -746,12 +892,15 @@ static int hidma_remove(struct platform_device *pdev)
#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id hidma_acpi_ids[] = {
{"QCOM8061"},
+ {"QCOM8062"},
{},
};
+MODULE_DEVICE_TABLE(acpi, hidma_acpi_ids);
#endif
static const struct of_device_id hidma_match[] = {
{.compatible = "qcom,hidma-1.0",},
+ {.compatible = "qcom,hidma-1.1",},
{},
};
MODULE_DEVICE_TABLE(of, hidma_match);
diff --git a/drivers/dma/qcom/hidma.h b/drivers/dma/qcom/hidma.h
index e52e20716303..c7d014235c32 100644
--- a/drivers/dma/qcom/hidma.h
+++ b/drivers/dma/qcom/hidma.h
@@ -46,6 +46,7 @@ struct hidma_tre {
};
struct hidma_lldev {
+ bool msi_support; /* flag indicating MSI support */
bool initialized; /* initialized flag */
u8 trch_state; /* trch_state of the device */
u8 evch_state; /* evch_state of the device */
@@ -58,7 +59,7 @@ struct hidma_lldev {
void __iomem *evca; /* Event Channel address */
struct hidma_tre
**pending_tre_list; /* Pointers to pending TREs */
- s32 pending_tre_count; /* Number of TREs pending */
+ atomic_t pending_tre_count; /* Number of TREs pending */
void *tre_ring; /* TRE ring */
dma_addr_t tre_dma; /* TRE ring to be shared with HW */
@@ -114,6 +115,7 @@ struct hidma_dev {
int irq;
int chidx;
u32 nr_descriptors;
+ int msi_virqbase;
struct hidma_lldev *lldev;
void __iomem *dev_trca;
@@ -128,6 +130,9 @@ struct hidma_dev {
struct dentry *debugfs;
struct dentry *stats;
+ /* sysfs entry for the channel id */
+ struct device_attribute *chid_attrs;
+
/* Task delivering issue_pending */
struct tasklet_struct task;
};
@@ -145,12 +150,14 @@ int hidma_ll_disable(struct hidma_lldev *lldev);
int hidma_ll_enable(struct hidma_lldev *llhndl);
void hidma_ll_set_transfer_params(struct hidma_lldev *llhndl, u32 tre_ch,
dma_addr_t src, dma_addr_t dest, u32 len, u32 flags);
+void hidma_ll_setup_irq(struct hidma_lldev *lldev, bool msi);
int hidma_ll_setup(struct hidma_lldev *lldev);
struct hidma_lldev *hidma_ll_init(struct device *dev, u32 max_channels,
void __iomem *trca, void __iomem *evca,
u8 chidx);
int hidma_ll_uninit(struct hidma_lldev *llhndl);
irqreturn_t hidma_ll_inthandler(int irq, void *arg);
+irqreturn_t hidma_ll_inthandler_msi(int irq, void *arg, int cause);
void hidma_cleanup_pending_tre(struct hidma_lldev *llhndl, u8 err_info,
u8 err_code);
int hidma_debug_init(struct hidma_dev *dmadev);
diff --git a/drivers/dma/qcom/hidma_dbg.c b/drivers/dma/qcom/hidma_dbg.c
index fa827e5ffd68..3bdcb8056a36 100644
--- a/drivers/dma/qcom/hidma_dbg.c
+++ b/drivers/dma/qcom/hidma_dbg.c
@@ -74,7 +74,8 @@ static void hidma_ll_devstats(struct seq_file *s, void *llhndl)
seq_printf(s, "tre_ring_handle=%pap\n", &lldev->tre_dma);
seq_printf(s, "tre_ring_size = 0x%x\n", lldev->tre_ring_size);
seq_printf(s, "tre_processed_off = 0x%x\n", lldev->tre_processed_off);
- seq_printf(s, "pending_tre_count=%d\n", lldev->pending_tre_count);
+ seq_printf(s, "pending_tre_count=%d\n",
+ atomic_read(&lldev->pending_tre_count));
seq_printf(s, "evca=%p\n", lldev->evca);
seq_printf(s, "evre_ring=%p\n", lldev->evre_ring);
seq_printf(s, "evre_ring_handle=%pap\n", &lldev->evre_dma);
@@ -164,7 +165,6 @@ static const struct file_operations hidma_dma_fops = {
void hidma_debug_uninit(struct hidma_dev *dmadev)
{
debugfs_remove_recursive(dmadev->debugfs);
- debugfs_remove_recursive(dmadev->stats);
}
int hidma_debug_init(struct hidma_dev *dmadev)
diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c
index 3224f24c577b..6645bdf0d151 100644
--- a/drivers/dma/qcom/hidma_ll.c
+++ b/drivers/dma/qcom/hidma_ll.c
@@ -198,13 +198,16 @@ static void hidma_ll_tre_complete(unsigned long arg)
}
}
-static int hidma_post_completed(struct hidma_lldev *lldev, int tre_iterator,
- u8 err_info, u8 err_code)
+static int hidma_post_completed(struct hidma_lldev *lldev, u8 err_info,
+ u8 err_code)
{
struct hidma_tre *tre;
unsigned long flags;
+ u32 tre_iterator;
spin_lock_irqsave(&lldev->lock, flags);
+
+ tre_iterator = lldev->tre_processed_off;
tre = lldev->pending_tre_list[tre_iterator / HIDMA_TRE_SIZE];
if (!tre) {
spin_unlock_irqrestore(&lldev->lock, flags);
@@ -218,12 +221,14 @@ static int hidma_post_completed(struct hidma_lldev *lldev, int tre_iterator,
* Keep track of pending TREs that SW is expecting to receive
* from HW. We got one now. Decrement our counter.
*/
- lldev->pending_tre_count--;
- if (lldev->pending_tre_count < 0) {
+ if (atomic_dec_return(&lldev->pending_tre_count) < 0) {
dev_warn(lldev->dev, "tre count mismatch on completion");
- lldev->pending_tre_count = 0;
+ atomic_set(&lldev->pending_tre_count, 0);
}
+ HIDMA_INCREMENT_ITERATOR(tre_iterator, HIDMA_TRE_SIZE,
+ lldev->tre_ring_size);
+ lldev->tre_processed_off = tre_iterator;
spin_unlock_irqrestore(&lldev->lock, flags);
tre->err_info = err_info;
@@ -245,13 +250,11 @@ static int hidma_post_completed(struct hidma_lldev *lldev, int tre_iterator,
static int hidma_handle_tre_completion(struct hidma_lldev *lldev)
{
u32 evre_ring_size = lldev->evre_ring_size;
- u32 tre_ring_size = lldev->tre_ring_size;
u32 err_info, err_code, evre_write_off;
- u32 tre_iterator, evre_iterator;
+ u32 evre_iterator;
u32 num_completed = 0;
evre_write_off = readl_relaxed(lldev->evca + HIDMA_EVCA_WRITE_PTR_REG);
- tre_iterator = lldev->tre_processed_off;
evre_iterator = lldev->evre_processed_off;
if ((evre_write_off > evre_ring_size) ||
@@ -274,12 +277,9 @@ static int hidma_handle_tre_completion(struct hidma_lldev *lldev)
err_code =
(cfg >> HIDMA_EVRE_CODE_BIT_POS) & HIDMA_EVRE_CODE_MASK;
- if (hidma_post_completed(lldev, tre_iterator, err_info,
- err_code))
+ if (hidma_post_completed(lldev, err_info, err_code))
break;
- HIDMA_INCREMENT_ITERATOR(tre_iterator, HIDMA_TRE_SIZE,
- tre_ring_size);
HIDMA_INCREMENT_ITERATOR(evre_iterator, HIDMA_EVRE_SIZE,
evre_ring_size);
@@ -291,21 +291,22 @@ static int hidma_handle_tre_completion(struct hidma_lldev *lldev)
evre_write_off =
readl_relaxed(lldev->evca + HIDMA_EVCA_WRITE_PTR_REG);
num_completed++;
+
+ /*
+ * An error interrupt might have arrived while we are processing
+ * the completed interrupt.
+ */
+ if (!hidma_ll_isenabled(lldev))
+ break;
}
if (num_completed) {
u32 evre_read_off = (lldev->evre_processed_off +
HIDMA_EVRE_SIZE * num_completed);
- u32 tre_read_off = (lldev->tre_processed_off +
- HIDMA_TRE_SIZE * num_completed);
-
evre_read_off = evre_read_off % evre_ring_size;
- tre_read_off = tre_read_off % tre_ring_size;
-
writel(evre_read_off, lldev->evca + HIDMA_EVCA_DOORBELL_REG);
/* record the last processed tre offset */
- lldev->tre_processed_off = tre_read_off;
lldev->evre_processed_off = evre_read_off;
}
@@ -315,27 +316,10 @@ static int hidma_handle_tre_completion(struct hidma_lldev *lldev)
void hidma_cleanup_pending_tre(struct hidma_lldev *lldev, u8 err_info,
u8 err_code)
{
- u32 tre_iterator;
- u32 tre_ring_size = lldev->tre_ring_size;
- int num_completed = 0;
- u32 tre_read_off;
-
- tre_iterator = lldev->tre_processed_off;
- while (lldev->pending_tre_count) {
- if (hidma_post_completed(lldev, tre_iterator, err_info,
- err_code))
+ while (atomic_read(&lldev->pending_tre_count)) {
+ if (hidma_post_completed(lldev, err_info, err_code))
break;
- HIDMA_INCREMENT_ITERATOR(tre_iterator, HIDMA_TRE_SIZE,
- tre_ring_size);
- num_completed++;
}
- tre_read_off = (lldev->tre_processed_off +
- HIDMA_TRE_SIZE * num_completed);
-
- tre_read_off = tre_read_off % tre_ring_size;
-
- /* record the last processed tre offset */
- lldev->tre_processed_off = tre_read_off;
}
static int hidma_ll_reset(struct hidma_lldev *lldev)
@@ -412,12 +396,24 @@ static int hidma_ll_reset(struct hidma_lldev *lldev)
* requests traditionally to the destination, this concept does not apply
* here for this HW.
*/
-irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
+static void hidma_ll_int_handler_internal(struct hidma_lldev *lldev, int cause)
{
- struct hidma_lldev *lldev = arg;
- u32 status;
- u32 enable;
- u32 cause;
+ if (cause & HIDMA_ERR_INT_MASK) {
+ dev_err(lldev->dev, "error 0x%x, disabling...\n",
+ cause);
+
+ /* Clear out pending interrupts */
+ writel(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+
+ /* No further submissions. */
+ hidma_ll_disable(lldev);
+
+ /* Driver completes the txn and intimates the client.*/
+ hidma_cleanup_pending_tre(lldev, 0xFF,
+ HIDMA_EVRE_STATUS_ERROR);
+
+ return;
+ }
/*
* Fine tuned for this HW...
@@ -426,35 +422,28 @@ irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
* read and write accessors are used for performance reasons due to
* interrupt delivery guarantees. Do not copy this code blindly and
* expect that to work.
+ *
+ * Try to consume as many EVREs as possible.
*/
+ hidma_handle_tre_completion(lldev);
+
+ /* We consumed TREs or there are pending TREs or EVREs. */
+ writel_relaxed(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+}
+
+irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
+{
+ struct hidma_lldev *lldev = arg;
+ u32 status;
+ u32 enable;
+ u32 cause;
+
status = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_STAT_REG);
enable = readl_relaxed(lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
cause = status & enable;
while (cause) {
- if (cause & HIDMA_ERR_INT_MASK) {
- dev_err(lldev->dev, "error 0x%x, disabling...\n",
- cause);
-
- /* Clear out pending interrupts */
- writel(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
-
- /* No further submissions. */
- hidma_ll_disable(lldev);
-
- /* Driver completes the txn and intimates the client.*/
- hidma_cleanup_pending_tre(lldev, 0xFF,
- HIDMA_EVRE_STATUS_ERROR);
- goto out;
- }
-
- /*
- * Try to consume as many EVREs as possible.
- */
- hidma_handle_tre_completion(lldev);
-
- /* We consumed TREs or there are pending TREs or EVREs. */
- writel_relaxed(cause, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+ hidma_ll_int_handler_internal(lldev, cause);
/*
* Another interrupt might have arrived while we are
@@ -465,7 +454,14 @@ irqreturn_t hidma_ll_inthandler(int chirq, void *arg)
cause = status & enable;
}
-out:
+ return IRQ_HANDLED;
+}
+
+irqreturn_t hidma_ll_inthandler_msi(int chirq, void *arg, int cause)
+{
+ struct hidma_lldev *lldev = arg;
+
+ hidma_ll_int_handler_internal(lldev, cause);
return IRQ_HANDLED;
}
@@ -548,7 +544,7 @@ void hidma_ll_queue_request(struct hidma_lldev *lldev, u32 tre_ch)
tre->err_code = 0;
tre->err_info = 0;
tre->queued = 1;
- lldev->pending_tre_count++;
+ atomic_inc(&lldev->pending_tre_count);
lldev->tre_write_offset = (lldev->tre_write_offset + HIDMA_TRE_SIZE)
% lldev->tre_ring_size;
spin_unlock_irqrestore(&lldev->lock, flags);
@@ -564,19 +560,8 @@ int hidma_ll_disable(struct hidma_lldev *lldev)
u32 val;
int ret;
- val = readl(lldev->evca + HIDMA_EVCA_CTRLSTS_REG);
- lldev->evch_state = HIDMA_CH_STATE(val);
- val = readl(lldev->trca + HIDMA_TRCA_CTRLSTS_REG);
- lldev->trch_state = HIDMA_CH_STATE(val);
-
- /* already suspended by this OS */
- if ((lldev->trch_state == HIDMA_CH_SUSPENDED) ||
- (lldev->evch_state == HIDMA_CH_SUSPENDED))
- return 0;
-
- /* already stopped by the manager */
- if ((lldev->trch_state == HIDMA_CH_STOPPED) ||
- (lldev->evch_state == HIDMA_CH_STOPPED))
+ /* The channel needs to be in working state */
+ if (!hidma_ll_isenabled(lldev))
return 0;
val = readl(lldev->trca + HIDMA_TRCA_CTRLSTS_REG);
@@ -654,7 +639,7 @@ int hidma_ll_setup(struct hidma_lldev *lldev)
u32 val;
u32 nr_tres = lldev->nr_tres;
- lldev->pending_tre_count = 0;
+ atomic_set(&lldev->pending_tre_count, 0);
lldev->tre_processed_off = 0;
lldev->evre_processed_off = 0;
lldev->tre_write_offset = 0;
@@ -691,17 +676,36 @@ int hidma_ll_setup(struct hidma_lldev *lldev)
writel(HIDMA_EVRE_SIZE * nr_tres,
lldev->evca + HIDMA_EVCA_RING_LEN_REG);
- /* support IRQ only for now */
+ /* configure interrupts */
+ hidma_ll_setup_irq(lldev, lldev->msi_support);
+
+ rc = hidma_ll_enable(lldev);
+ if (rc)
+ return rc;
+
+ return rc;
+}
+
+void hidma_ll_setup_irq(struct hidma_lldev *lldev, bool msi)
+{
+ u32 val;
+
+ lldev->msi_support = msi;
+
+ /* disable interrupts again after reset */
+ writel(0, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
+ writel(0, lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
+
+ /* support IRQ by default */
val = readl(lldev->evca + HIDMA_EVCA_INTCTRL_REG);
val &= ~0xF;
- val |= 0x1;
+ if (!lldev->msi_support)
+ val = val | 0x1;
writel(val, lldev->evca + HIDMA_EVCA_INTCTRL_REG);
/* clear all pending interrupts and enable them */
writel(ENABLE_IRQS, lldev->evca + HIDMA_EVCA_IRQ_CLR_REG);
writel(ENABLE_IRQS, lldev->evca + HIDMA_EVCA_IRQ_EN_REG);
-
- return hidma_ll_enable(lldev);
}
struct hidma_lldev *hidma_ll_init(struct device *dev, u32 nr_tres,
@@ -816,7 +820,7 @@ int hidma_ll_uninit(struct hidma_lldev *lldev)
tasklet_kill(&lldev->task);
memset(lldev->trepool, 0, required_bytes);
lldev->trepool = NULL;
- lldev->pending_tre_count = 0;
+ atomic_set(&lldev->pending_tre_count, 0);
lldev->tre_write_offset = 0;
rc = hidma_ll_reset(lldev);
diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c
index 82f36e466083..f847d32cc4b5 100644
--- a/drivers/dma/qcom/hidma_mgmt.c
+++ b/drivers/dma/qcom/hidma_mgmt.c
@@ -282,6 +282,7 @@ static const struct acpi_device_id hidma_mgmt_acpi_ids[] = {
{"QCOM8060"},
{},
};
+MODULE_DEVICE_TABLE(acpi, hidma_mgmt_acpi_ids);
#endif
static const struct of_device_id hidma_mgmt_match[] = {
@@ -375,8 +376,15 @@ static int __init hidma_mgmt_of_populate_channels(struct device_node *np)
ret = PTR_ERR(new_pdev);
goto out;
}
+ of_node_get(child);
+ new_pdev->dev.of_node = child;
of_dma_configure(&new_pdev->dev, child);
-
+ /*
+ * It is assumed that calling of_msi_configure is safe on
+ * platforms with or without MSI support.
+ */
+ of_msi_configure(&new_pdev->dev, child);
+ of_node_put(child);
kfree(res);
res = NULL;
}
@@ -395,7 +403,6 @@ static int __init hidma_mgmt_init(void)
for_each_matching_node(child, hidma_mgmt_match) {
/* device tree based firmware here */
hidma_mgmt_of_populate_channels(child);
- of_node_put(child);
}
#endif
platform_driver_register(&hidma_mgmt_driver);
diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c
index 3c579abbabb7..f04c4702d98b 100644
--- a/drivers/dma/s3c24xx-dma.c
+++ b/drivers/dma/s3c24xx-dma.c
@@ -289,16 +289,11 @@ static
struct s3c24xx_dma_phy *s3c24xx_dma_get_phy(struct s3c24xx_dma_chan *s3cchan)
{
struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
- const struct s3c24xx_dma_platdata *pdata = s3cdma->pdata;
- struct s3c24xx_dma_channel *cdata;
struct s3c24xx_dma_phy *phy = NULL;
unsigned long flags;
int i;
int ret;
- if (s3cchan->slave)
- cdata = &pdata->channels[s3cchan->id];
-
for (i = 0; i < s3cdma->pdata->num_phy_channels; i++) {
phy = &s3cdma->phy_chans[i];
diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c
index 06ecdc38cee0..72c649713ace 100644
--- a/drivers/dma/sh/usb-dmac.c
+++ b/drivers/dma/sh/usb-dmac.c
@@ -652,7 +652,6 @@ static bool usb_dmac_chan_filter(struct dma_chan *chan, void *arg)
static struct dma_chan *usb_dmac_of_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
- struct usb_dmac_chan *uchan;
struct dma_chan *chan;
dma_cap_mask_t mask;
@@ -667,8 +666,6 @@ static struct dma_chan *usb_dmac_of_xlate(struct of_phandle_args *dma_spec,
if (!chan)
return NULL;
- uchan = to_usb_dmac_chan(chan);
-
return chan;
}
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 8f62edad51be..a0733ac3edb1 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -1011,7 +1011,6 @@ static int __maybe_unused sirfsoc_dma_pm_suspend(struct device *dev)
{
struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
struct sirfsoc_dma_regs *save = &sdma->regs_save;
- struct sirfsoc_dma_desc *sdesc;
struct sirfsoc_dma_chan *schan;
int ch;
int ret;
@@ -1044,9 +1043,6 @@ static int __maybe_unused sirfsoc_dma_pm_suspend(struct device *dev)
schan = &sdma->channels[ch];
if (list_empty(&schan->active))
continue;
- sdesc = list_first_entry(&schan->active,
- struct sirfsoc_dma_desc,
- node);
save->ctrl[ch] = readl_relaxed(sdma->base +
ch * 0x10 + SIRFSOC_DMA_CH_CTRL);
}
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 307547f4848d..3688d0873a3e 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -527,13 +527,12 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
{
struct stm32_dma_chan *chan = devid;
struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan);
- u32 status, scr, sfcr;
+ u32 status, scr;
spin_lock(&chan->vchan.lock);
status = stm32_dma_irq_status(chan);
scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id));
- sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id));
if ((status & STM32_DMA_TCI) && (scr & STM32_DMA_SCR_TCIE)) {
stm32_dma_irq_clear(chan, STM32_DMA_TCI);
@@ -574,15 +573,12 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
int src_bus_width, dst_bus_width;
int src_burst_size, dst_burst_size;
u32 src_maxburst, dst_maxburst;
- dma_addr_t src_addr, dst_addr;
u32 dma_scr = 0;
src_addr_width = chan->dma_sconfig.src_addr_width;
dst_addr_width = chan->dma_sconfig.dst_addr_width;
src_maxburst = chan->dma_sconfig.src_maxburst;
dst_maxburst = chan->dma_sconfig.dst_maxburst;
- src_addr = chan->dma_sconfig.src_addr;
- dst_addr = chan->dma_sconfig.dst_addr;
switch (direction) {
case DMA_MEM_TO_DEV:
diff --git a/drivers/dma/zx296702_dma.c b/drivers/dma/zx296702_dma.c
index 245d759d5ffc..380276d078b2 100644
--- a/drivers/dma/zx296702_dma.c
+++ b/drivers/dma/zx296702_dma.c
@@ -435,13 +435,12 @@ static struct zx_dma_desc_sw *zx_alloc_desc_resource(int num,
if (!ds)
return NULL;
- ds->desc_hw = dma_pool_alloc(d->pool, GFP_NOWAIT, &ds->desc_hw_lli);
+ ds->desc_hw = dma_pool_zalloc(d->pool, GFP_NOWAIT, &ds->desc_hw_lli);
if (!ds->desc_hw) {
dev_dbg(chan->device->dev, "vch %p: dma alloc fail\n", &c->vc);
kfree(ds);
return NULL;
}
- memset(ds->desc_hw, 0, sizeof(struct zx_desc_hw) * num);
ds->desc_num = num;
return ds;
}
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index bca172d42c74..1867f0d1389b 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -8,6 +8,17 @@ menu "Firmware Drivers"
config ARM_PSCI_FW
bool
+config ARM_PSCI_CHECKER
+ bool "ARM PSCI checker"
+ depends on ARM_PSCI_FW && HOTPLUG_CPU && !TORTURE_TEST
+ help
+ Run the PSCI checker during startup. This checks that hotplug and
+ suspend operations work correctly when using PSCI.
+
+ The torture tests may interfere with the PSCI checker by turning CPUs
+ on and off through hotplug, so for now torture tests and PSCI checker
+ are mutually exclusive.
+
config ARM_SCPI_PROTOCOL
tristate "ARM System Control and Power Interface (SCPI) Message Protocol"
depends on MAILBOX
@@ -203,6 +214,21 @@ config QCOM_SCM_64
def_bool y
depends on QCOM_SCM && ARM64
+config TI_SCI_PROTOCOL
+ tristate "TI System Control Interface (TISCI) Message Protocol"
+ depends on TI_MESSAGE_MANAGER
+ help
+ TI System Control Interface (TISCI) Message Protocol is used to manage
+ compute systems such as ARM, DSP etc with the system controller in
+ complex System on Chip(SoC) such as those found on certain keystone
+ generation SoC from TI.
+
+ System controller provides various facilities including power
+ management function support.
+
+ This protocol library is used by client drivers to use the features
+ provided by the system controller.
+
config HAVE_ARM_SMCCC
bool
@@ -210,5 +236,6 @@ source "drivers/firmware/broadcom/Kconfig"
source "drivers/firmware/google/Kconfig"
source "drivers/firmware/efi/Kconfig"
source "drivers/firmware/meson/Kconfig"
+source "drivers/firmware/tegra/Kconfig"
endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 898ac41fa8b3..a37f12e8d137 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -2,6 +2,7 @@
# Makefile for the linux kernel.
#
obj-$(CONFIG_ARM_PSCI_FW) += psci.o
+obj-$(CONFIG_ARM_PSCI_CHECKER) += psci_checker.o
obj-$(CONFIG_ARM_SCPI_PROTOCOL) += arm_scpi.o
obj-$(CONFIG_ARM_SCPI_POWER_DOMAIN) += scpi_pm_domain.o
obj-$(CONFIG_DMI) += dmi_scan.o
@@ -20,9 +21,11 @@ obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o
obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o
CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
+obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
obj-y += broadcom/
obj-y += meson/
obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
obj-$(CONFIG_EFI) += efi/
obj-$(CONFIG_UEFI_CPER) += efi/
+obj-y += tegra/
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index ce2bc2a38101..70e13230d8db 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -50,20 +50,27 @@
#define CMD_TOKEN_ID_MASK 0xff
#define CMD_DATA_SIZE_SHIFT 16
#define CMD_DATA_SIZE_MASK 0x1ff
+#define CMD_LEGACY_DATA_SIZE_SHIFT 20
+#define CMD_LEGACY_DATA_SIZE_MASK 0x1ff
#define PACK_SCPI_CMD(cmd_id, tx_sz) \
((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
(((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
#define ADD_SCPI_TOKEN(cmd, token) \
((cmd) |= (((token) & CMD_TOKEN_ID_MASK) << CMD_TOKEN_ID_SHIFT))
+#define PACK_LEGACY_SCPI_CMD(cmd_id, tx_sz) \
+ ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
+ (((tx_sz) & CMD_LEGACY_DATA_SIZE_MASK) << CMD_LEGACY_DATA_SIZE_SHIFT))
#define CMD_SIZE(cmd) (((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK)
+#define CMD_LEGACY_SIZE(cmd) (((cmd) >> CMD_LEGACY_DATA_SIZE_SHIFT) & \
+ CMD_LEGACY_DATA_SIZE_MASK)
#define CMD_UNIQ_MASK (CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK)
#define CMD_XTRACT_UNIQ(cmd) ((cmd) & CMD_UNIQ_MASK)
#define SCPI_SLOT 0
#define MAX_DVFS_DOMAINS 8
-#define MAX_DVFS_OPPS 8
+#define MAX_DVFS_OPPS 16
#define DVFS_LATENCY(hdr) (le32_to_cpu(hdr) >> 16)
#define DVFS_OPP_COUNT(hdr) ((le32_to_cpu(hdr) >> 8) & 0xff)
@@ -99,6 +106,7 @@ enum scpi_error_codes {
SCPI_ERR_MAX
};
+/* SCPI Standard commands */
enum scpi_std_cmd {
SCPI_CMD_INVALID = 0x00,
SCPI_CMD_SCPI_READY = 0x01,
@@ -132,6 +140,108 @@ enum scpi_std_cmd {
SCPI_CMD_COUNT
};
+/* SCPI Legacy Commands */
+enum legacy_scpi_std_cmd {
+ LEGACY_SCPI_CMD_INVALID = 0x00,
+ LEGACY_SCPI_CMD_SCPI_READY = 0x01,
+ LEGACY_SCPI_CMD_SCPI_CAPABILITIES = 0x02,
+ LEGACY_SCPI_CMD_EVENT = 0x03,
+ LEGACY_SCPI_CMD_SET_CSS_PWR_STATE = 0x04,
+ LEGACY_SCPI_CMD_GET_CSS_PWR_STATE = 0x05,
+ LEGACY_SCPI_CMD_CFG_PWR_STATE_STAT = 0x06,
+ LEGACY_SCPI_CMD_GET_PWR_STATE_STAT = 0x07,
+ LEGACY_SCPI_CMD_SYS_PWR_STATE = 0x08,
+ LEGACY_SCPI_CMD_L2_READY = 0x09,
+ LEGACY_SCPI_CMD_SET_AP_TIMER = 0x0a,
+ LEGACY_SCPI_CMD_CANCEL_AP_TIME = 0x0b,
+ LEGACY_SCPI_CMD_DVFS_CAPABILITIES = 0x0c,
+ LEGACY_SCPI_CMD_GET_DVFS_INFO = 0x0d,
+ LEGACY_SCPI_CMD_SET_DVFS = 0x0e,
+ LEGACY_SCPI_CMD_GET_DVFS = 0x0f,
+ LEGACY_SCPI_CMD_GET_DVFS_STAT = 0x10,
+ LEGACY_SCPI_CMD_SET_RTC = 0x11,
+ LEGACY_SCPI_CMD_GET_RTC = 0x12,
+ LEGACY_SCPI_CMD_CLOCK_CAPABILITIES = 0x13,
+ LEGACY_SCPI_CMD_SET_CLOCK_INDEX = 0x14,
+ LEGACY_SCPI_CMD_SET_CLOCK_VALUE = 0x15,
+ LEGACY_SCPI_CMD_GET_CLOCK_VALUE = 0x16,
+ LEGACY_SCPI_CMD_PSU_CAPABILITIES = 0x17,
+ LEGACY_SCPI_CMD_SET_PSU = 0x18,
+ LEGACY_SCPI_CMD_GET_PSU = 0x19,
+ LEGACY_SCPI_CMD_SENSOR_CAPABILITIES = 0x1a,
+ LEGACY_SCPI_CMD_SENSOR_INFO = 0x1b,
+ LEGACY_SCPI_CMD_SENSOR_VALUE = 0x1c,
+ LEGACY_SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d,
+ LEGACY_SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e,
+ LEGACY_SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f,
+ LEGACY_SCPI_CMD_COUNT
+};
+
+/* List all commands that are required to go through the high priority link */
+static int legacy_hpriority_cmds[] = {
+ LEGACY_SCPI_CMD_GET_CSS_PWR_STATE,
+ LEGACY_SCPI_CMD_CFG_PWR_STATE_STAT,
+ LEGACY_SCPI_CMD_GET_PWR_STATE_STAT,
+ LEGACY_SCPI_CMD_SET_DVFS,
+ LEGACY_SCPI_CMD_GET_DVFS,
+ LEGACY_SCPI_CMD_SET_RTC,
+ LEGACY_SCPI_CMD_GET_RTC,
+ LEGACY_SCPI_CMD_SET_CLOCK_INDEX,
+ LEGACY_SCPI_CMD_SET_CLOCK_VALUE,
+ LEGACY_SCPI_CMD_GET_CLOCK_VALUE,
+ LEGACY_SCPI_CMD_SET_PSU,
+ LEGACY_SCPI_CMD_GET_PSU,
+ LEGACY_SCPI_CMD_SENSOR_CFG_PERIODIC,
+ LEGACY_SCPI_CMD_SENSOR_CFG_BOUNDS,
+};
+
+/* List all commands used by this driver, used as indexes */
+enum scpi_drv_cmds {
+ CMD_SCPI_CAPABILITIES = 0,
+ CMD_GET_CLOCK_INFO,
+ CMD_GET_CLOCK_VALUE,
+ CMD_SET_CLOCK_VALUE,
+ CMD_GET_DVFS,
+ CMD_SET_DVFS,
+ CMD_GET_DVFS_INFO,
+ CMD_SENSOR_CAPABILITIES,
+ CMD_SENSOR_INFO,
+ CMD_SENSOR_VALUE,
+ CMD_SET_DEVICE_PWR_STATE,
+ CMD_GET_DEVICE_PWR_STATE,
+ CMD_MAX_COUNT,
+};
+
+static int scpi_std_commands[CMD_MAX_COUNT] = {
+ SCPI_CMD_SCPI_CAPABILITIES,
+ SCPI_CMD_GET_CLOCK_INFO,
+ SCPI_CMD_GET_CLOCK_VALUE,
+ SCPI_CMD_SET_CLOCK_VALUE,
+ SCPI_CMD_GET_DVFS,
+ SCPI_CMD_SET_DVFS,
+ SCPI_CMD_GET_DVFS_INFO,
+ SCPI_CMD_SENSOR_CAPABILITIES,
+ SCPI_CMD_SENSOR_INFO,
+ SCPI_CMD_SENSOR_VALUE,
+ SCPI_CMD_SET_DEVICE_PWR_STATE,
+ SCPI_CMD_GET_DEVICE_PWR_STATE,
+};
+
+static int scpi_legacy_commands[CMD_MAX_COUNT] = {
+ LEGACY_SCPI_CMD_SCPI_CAPABILITIES,
+ -1, /* GET_CLOCK_INFO */
+ LEGACY_SCPI_CMD_GET_CLOCK_VALUE,
+ LEGACY_SCPI_CMD_SET_CLOCK_VALUE,
+ LEGACY_SCPI_CMD_GET_DVFS,
+ LEGACY_SCPI_CMD_SET_DVFS,
+ LEGACY_SCPI_CMD_GET_DVFS_INFO,
+ LEGACY_SCPI_CMD_SENSOR_CAPABILITIES,
+ LEGACY_SCPI_CMD_SENSOR_INFO,
+ LEGACY_SCPI_CMD_SENSOR_VALUE,
+ -1, /* SET_DEVICE_PWR_STATE */
+ -1, /* GET_DEVICE_PWR_STATE */
+};
+
struct scpi_xfer {
u32 slot; /* has to be first element */
u32 cmd;
@@ -160,7 +270,10 @@ struct scpi_chan {
struct scpi_drvinfo {
u32 protocol_version;
u32 firmware_version;
+ bool is_legacy;
int num_chans;
+ int *commands;
+ DECLARE_BITMAP(cmd_priority, LEGACY_SCPI_CMD_COUNT);
atomic_t next_chan;
struct scpi_ops *scpi_ops;
struct scpi_chan *channels;
@@ -177,6 +290,11 @@ struct scpi_shared_mem {
u8 payload[0];
} __packed;
+struct legacy_scpi_shared_mem {
+ __le32 status;
+ u8 payload[0];
+} __packed;
+
struct scp_capabilities {
__le32 protocol_version;
__le32 event_version;
@@ -202,6 +320,12 @@ struct clk_set_value {
__le32 rate;
} __packed;
+struct legacy_clk_set_value {
+ __le32 rate;
+ __le16 id;
+ __le16 reserved;
+} __packed;
+
struct dvfs_info {
__le32 header;
struct {
@@ -273,19 +397,43 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd)
return;
}
- list_for_each_entry(t, &ch->rx_pending, node)
- if (CMD_XTRACT_UNIQ(t->cmd) == CMD_XTRACT_UNIQ(cmd)) {
- list_del(&t->node);
- match = t;
- break;
- }
+ /* Command type is not replied by the SCP Firmware in legacy Mode
+ * We should consider that command is the head of pending RX commands
+ * if the list is not empty. In TX only mode, the list would be empty.
+ */
+ if (scpi_info->is_legacy) {
+ match = list_first_entry(&ch->rx_pending, struct scpi_xfer,
+ node);
+ list_del(&match->node);
+ } else {
+ list_for_each_entry(t, &ch->rx_pending, node)
+ if (CMD_XTRACT_UNIQ(t->cmd) == CMD_XTRACT_UNIQ(cmd)) {
+ list_del(&t->node);
+ match = t;
+ break;
+ }
+ }
/* check if wait_for_completion is in progress or timed-out */
if (match && !completion_done(&match->done)) {
- struct scpi_shared_mem *mem = ch->rx_payload;
- unsigned int len = min(match->rx_len, CMD_SIZE(cmd));
+ unsigned int len;
+
+ if (scpi_info->is_legacy) {
+ struct legacy_scpi_shared_mem *mem = ch->rx_payload;
+
+ /* RX Length is not replied by the legacy Firmware */
+ len = match->rx_len;
+
+ match->status = le32_to_cpu(mem->status);
+ memcpy_fromio(match->rx_buf, mem->payload, len);
+ } else {
+ struct scpi_shared_mem *mem = ch->rx_payload;
+
+ len = min(match->rx_len, CMD_SIZE(cmd));
+
+ match->status = le32_to_cpu(mem->status);
+ memcpy_fromio(match->rx_buf, mem->payload, len);
+ }
- match->status = le32_to_cpu(mem->status);
- memcpy_fromio(match->rx_buf, mem->payload, len);
if (match->rx_len > len)
memset(match->rx_buf + len, 0, match->rx_len - len);
complete(&match->done);
@@ -297,7 +445,10 @@ static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
{
struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
struct scpi_shared_mem *mem = ch->rx_payload;
- u32 cmd = le32_to_cpu(mem->command);
+ u32 cmd = 0;
+
+ if (!scpi_info->is_legacy)
+ cmd = le32_to_cpu(mem->command);
scpi_process_cmd(ch, cmd);
}
@@ -309,8 +460,13 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg)
struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
struct scpi_shared_mem *mem = (struct scpi_shared_mem *)ch->tx_payload;
- if (t->tx_buf)
- memcpy_toio(mem->payload, t->tx_buf, t->tx_len);
+ if (t->tx_buf) {
+ if (scpi_info->is_legacy)
+ memcpy_toio(ch->tx_payload, t->tx_buf, t->tx_len);
+ else
+ memcpy_toio(mem->payload, t->tx_buf, t->tx_len);
+ }
+
if (t->rx_buf) {
if (!(++ch->token))
++ch->token;
@@ -319,7 +475,9 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg)
list_add_tail(&t->node, &ch->rx_pending);
spin_unlock_irqrestore(&ch->rx_lock, flags);
}
- mem->command = cpu_to_le32(t->cmd);
+
+ if (!scpi_info->is_legacy)
+ mem->command = cpu_to_le32(t->cmd);
}
static struct scpi_xfer *get_scpi_xfer(struct scpi_chan *ch)
@@ -344,23 +502,38 @@ static void put_scpi_xfer(struct scpi_xfer *t, struct scpi_chan *ch)
mutex_unlock(&ch->xfers_lock);
}
-static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len,
+static int scpi_send_message(u8 idx, void *tx_buf, unsigned int tx_len,
void *rx_buf, unsigned int rx_len)
{
int ret;
u8 chan;
+ u8 cmd;
struct scpi_xfer *msg;
struct scpi_chan *scpi_chan;
- chan = atomic_inc_return(&scpi_info->next_chan) % scpi_info->num_chans;
+ if (scpi_info->commands[idx] < 0)
+ return -EOPNOTSUPP;
+
+ cmd = scpi_info->commands[idx];
+
+ if (scpi_info->is_legacy)
+ chan = test_bit(cmd, scpi_info->cmd_priority) ? 1 : 0;
+ else
+ chan = atomic_inc_return(&scpi_info->next_chan) %
+ scpi_info->num_chans;
scpi_chan = scpi_info->channels + chan;
msg = get_scpi_xfer(scpi_chan);
if (!msg)
return -ENOMEM;
- msg->slot = BIT(SCPI_SLOT);
- msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
+ if (scpi_info->is_legacy) {
+ msg->cmd = PACK_LEGACY_SCPI_CMD(cmd, tx_len);
+ msg->slot = msg->cmd;
+ } else {
+ msg->slot = BIT(SCPI_SLOT);
+ msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
+ }
msg->tx_buf = tx_buf;
msg->tx_len = tx_len;
msg->rx_buf = rx_buf;
@@ -397,7 +570,7 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
struct clk_get_info clk;
__le16 le_clk_id = cpu_to_le16(clk_id);
- ret = scpi_send_message(SCPI_CMD_GET_CLOCK_INFO, &le_clk_id,
+ ret = scpi_send_message(CMD_GET_CLOCK_INFO, &le_clk_id,
sizeof(le_clk_id), &clk, sizeof(clk));
if (!ret) {
*min = le32_to_cpu(clk.min_rate);
@@ -412,8 +585,9 @@ static unsigned long scpi_clk_get_val(u16 clk_id)
struct clk_get_value clk;
__le16 le_clk_id = cpu_to_le16(clk_id);
- ret = scpi_send_message(SCPI_CMD_GET_CLOCK_VALUE, &le_clk_id,
+ ret = scpi_send_message(CMD_GET_CLOCK_VALUE, &le_clk_id,
sizeof(le_clk_id), &clk, sizeof(clk));
+
return ret ? ret : le32_to_cpu(clk.rate);
}
@@ -425,7 +599,19 @@ static int scpi_clk_set_val(u16 clk_id, unsigned long rate)
.rate = cpu_to_le32(rate)
};
- return scpi_send_message(SCPI_CMD_SET_CLOCK_VALUE, &clk, sizeof(clk),
+ return scpi_send_message(CMD_SET_CLOCK_VALUE, &clk, sizeof(clk),
+ &stat, sizeof(stat));
+}
+
+static int legacy_scpi_clk_set_val(u16 clk_id, unsigned long rate)
+{
+ int stat;
+ struct legacy_clk_set_value clk = {
+ .id = cpu_to_le16(clk_id),
+ .rate = cpu_to_le32(rate)
+ };
+
+ return scpi_send_message(CMD_SET_CLOCK_VALUE, &clk, sizeof(clk),
&stat, sizeof(stat));
}
@@ -434,8 +620,9 @@ static int scpi_dvfs_get_idx(u8 domain)
int ret;
u8 dvfs_idx;
- ret = scpi_send_message(SCPI_CMD_GET_DVFS, &domain, sizeof(domain),
+ ret = scpi_send_message(CMD_GET_DVFS, &domain, sizeof(domain),
&dvfs_idx, sizeof(dvfs_idx));
+
return ret ? ret : dvfs_idx;
}
@@ -444,7 +631,7 @@ static int scpi_dvfs_set_idx(u8 domain, u8 index)
int stat;
struct dvfs_set dvfs = {domain, index};
- return scpi_send_message(SCPI_CMD_SET_DVFS, &dvfs, sizeof(dvfs),
+ return scpi_send_message(CMD_SET_DVFS, &dvfs, sizeof(dvfs),
&stat, sizeof(stat));
}
@@ -468,9 +655,8 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
if (scpi_info->dvfs[domain]) /* data already populated */
return scpi_info->dvfs[domain];
- ret = scpi_send_message(SCPI_CMD_GET_DVFS_INFO, &domain, sizeof(domain),
+ ret = scpi_send_message(CMD_GET_DVFS_INFO, &domain, sizeof(domain),
&buf, sizeof(buf));
-
if (ret)
return ERR_PTR(ret);
@@ -503,7 +689,7 @@ static int scpi_sensor_get_capability(u16 *sensors)
struct sensor_capabilities cap_buf;
int ret;
- ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf,
+ ret = scpi_send_message(CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf,
sizeof(cap_buf));
if (!ret)
*sensors = le16_to_cpu(cap_buf.sensors);
@@ -517,7 +703,7 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info)
struct _scpi_sensor_info _info;
int ret;
- ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, sizeof(id),
+ ret = scpi_send_message(CMD_SENSOR_INFO, &id, sizeof(id),
&_info, sizeof(_info));
if (!ret) {
memcpy(info, &_info, sizeof(*info));
@@ -533,7 +719,7 @@ static int scpi_sensor_get_value(u16 sensor, u64 *val)
struct sensor_value buf;
int ret;
- ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &id, sizeof(id),
+ ret = scpi_send_message(CMD_SENSOR_VALUE, &id, sizeof(id),
&buf, sizeof(buf));
if (!ret)
*val = (u64)le32_to_cpu(buf.hi_val) << 32 |
@@ -548,7 +734,7 @@ static int scpi_device_get_power_state(u16 dev_id)
u8 pstate;
__le16 id = cpu_to_le16(dev_id);
- ret = scpi_send_message(SCPI_CMD_GET_DEVICE_PWR_STATE, &id,
+ ret = scpi_send_message(CMD_GET_DEVICE_PWR_STATE, &id,
sizeof(id), &pstate, sizeof(pstate));
return ret ? ret : pstate;
}
@@ -561,7 +747,7 @@ static int scpi_device_set_power_state(u16 dev_id, u8 pstate)
.pstate = pstate,
};
- return scpi_send_message(SCPI_CMD_SET_DEVICE_PWR_STATE, &dev_set,
+ return scpi_send_message(CMD_SET_DEVICE_PWR_STATE, &dev_set,
sizeof(dev_set), &stat, sizeof(stat));
}
@@ -591,12 +777,16 @@ static int scpi_init_versions(struct scpi_drvinfo *info)
int ret;
struct scp_capabilities caps;
- ret = scpi_send_message(SCPI_CMD_SCPI_CAPABILITIES, NULL, 0,
+ ret = scpi_send_message(CMD_SCPI_CAPABILITIES, NULL, 0,
&caps, sizeof(caps));
if (!ret) {
info->protocol_version = le32_to_cpu(caps.protocol_version);
info->firmware_version = le32_to_cpu(caps.platform_version);
}
+ /* Ignore error if not implemented */
+ if (scpi_info->is_legacy && ret == -EOPNOTSUPP)
+ return 0;
+
return ret;
}
@@ -681,6 +871,11 @@ static int scpi_alloc_xfer_list(struct device *dev, struct scpi_chan *ch)
return 0;
}
+static const struct of_device_id legacy_scpi_of_match[] = {
+ {.compatible = "arm,scpi-pre-1.0"},
+ {},
+};
+
static int scpi_probe(struct platform_device *pdev)
{
int count, idx, ret;
@@ -693,6 +888,9 @@ static int scpi_probe(struct platform_device *pdev)
if (!scpi_info)
return -ENOMEM;
+ if (of_match_device(legacy_scpi_of_match, &pdev->dev))
+ scpi_info->is_legacy = true;
+
count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
if (count < 0) {
dev_err(dev, "no mboxes property in '%s'\n", np->full_name);
@@ -755,8 +953,21 @@ err:
scpi_info->channels = scpi_chan;
scpi_info->num_chans = count;
+ scpi_info->commands = scpi_std_commands;
+
platform_set_drvdata(pdev, scpi_info);
+ if (scpi_info->is_legacy) {
+ /* Replace with legacy variants */
+ scpi_ops.clk_set_val = legacy_scpi_clk_set_val;
+ scpi_info->commands = scpi_legacy_commands;
+
+ /* Fill priority bitmap */
+ for (idx = 0; idx < ARRAY_SIZE(legacy_hpriority_cmds); idx++)
+ set_bit(legacy_hpriority_cmds[idx],
+ scpi_info->cmd_priority);
+ }
+
ret = scpi_init_versions(scpi_info);
if (ret) {
dev_err(dev, "incorrect or no SCP firmware found\n");
@@ -781,6 +992,7 @@ err:
static const struct of_device_id scpi_of_match[] = {
{.compatible = "arm,scpi"},
+ {.compatible = "arm,scpi-pre-1.0"},
{},
};
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 8263429e21b8..6c60a5087caf 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -630,7 +630,7 @@ int __init psci_dt_init(void)
np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
- if (!np)
+ if (!np || !of_device_is_available(np))
return -ENODEV;
init_fn = (psci_initcall_t)matched_np->data;
diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c
new file mode 100644
index 000000000000..44bdb78f837b
--- /dev/null
+++ b/drivers/firmware/psci_checker.c
@@ -0,0 +1,490 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/atomic.h>
+#include <linux/completion.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+#include <linux/tick.h>
+#include <linux/topology.h>
+
+#include <asm/cpuidle.h>
+
+#include <uapi/linux/psci.h>
+
+#define NUM_SUSPEND_CYCLE (10)
+
+static unsigned int nb_available_cpus;
+static int tos_resident_cpu = -1;
+
+static atomic_t nb_active_threads;
+static struct completion suspend_threads_started =
+ COMPLETION_INITIALIZER(suspend_threads_started);
+static struct completion suspend_threads_done =
+ COMPLETION_INITIALIZER(suspend_threads_done);
+
+/*
+ * We assume that PSCI operations are used if they are available. This is not
+ * necessarily true on arm64, since the decision is based on the
+ * "enable-method" property of each CPU in the DT, but given that there is no
+ * arch-specific way to check this, we assume that the DT is sensible.
+ */
+static int psci_ops_check(void)
+{
+ int migrate_type = -1;
+ int cpu;
+
+ if (!(psci_ops.cpu_off && psci_ops.cpu_on && psci_ops.cpu_suspend)) {
+ pr_warn("Missing PSCI operations, aborting tests\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (psci_ops.migrate_info_type)
+ migrate_type = psci_ops.migrate_info_type();
+
+ if (migrate_type == PSCI_0_2_TOS_UP_MIGRATE ||
+ migrate_type == PSCI_0_2_TOS_UP_NO_MIGRATE) {
+ /* There is a UP Trusted OS, find on which core it resides. */
+ for_each_online_cpu(cpu)
+ if (psci_tos_resident_on(cpu)) {
+ tos_resident_cpu = cpu;
+ break;
+ }
+ if (tos_resident_cpu == -1)
+ pr_warn("UP Trusted OS resides on no online CPU\n");
+ }
+
+ return 0;
+}
+
+static int find_clusters(const struct cpumask *cpus,
+ const struct cpumask **clusters)
+{
+ unsigned int nb = 0;
+ cpumask_var_t tmp;
+
+ if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_copy(tmp, cpus);
+
+ while (!cpumask_empty(tmp)) {
+ const struct cpumask *cluster =
+ topology_core_cpumask(cpumask_any(tmp));
+
+ clusters[nb++] = cluster;
+ cpumask_andnot(tmp, tmp, cluster);
+ }
+
+ free_cpumask_var(tmp);
+ return nb;
+}
+
+/*
+ * offlined_cpus is a temporary array but passing it as an argument avoids
+ * multiple allocations.
+ */
+static unsigned int down_and_up_cpus(const struct cpumask *cpus,
+ struct cpumask *offlined_cpus)
+{
+ int cpu;
+ int err = 0;
+
+ cpumask_clear(offlined_cpus);
+
+ /* Try to power down all CPUs in the mask. */
+ for_each_cpu(cpu, cpus) {
+ int ret = cpu_down(cpu);
+
+ /*
+ * cpu_down() checks the number of online CPUs before the TOS
+ * resident CPU.
+ */
+ if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
+ if (ret != -EBUSY) {
+ pr_err("Unexpected return code %d while trying "
+ "to power down last online CPU %d\n",
+ ret, cpu);
+ ++err;
+ }
+ } else if (cpu == tos_resident_cpu) {
+ if (ret != -EPERM) {
+ pr_err("Unexpected return code %d while trying "
+ "to power down TOS resident CPU %d\n",
+ ret, cpu);
+ ++err;
+ }
+ } else if (ret != 0) {
+ pr_err("Error occurred (%d) while trying "
+ "to power down CPU %d\n", ret, cpu);
+ ++err;
+ }
+
+ if (ret == 0)
+ cpumask_set_cpu(cpu, offlined_cpus);
+ }
+
+ /* Try to power up all the CPUs that have been offlined. */
+ for_each_cpu(cpu, offlined_cpus) {
+ int ret = cpu_up(cpu);
+
+ if (ret != 0) {
+ pr_err("Error occurred (%d) while trying "
+ "to power up CPU %d\n", ret, cpu);
+ ++err;
+ } else {
+ cpumask_clear_cpu(cpu, offlined_cpus);
+ }
+ }
+
+ /*
+ * Something went bad at some point and some CPUs could not be turned
+ * back on.
+ */
+ WARN_ON(!cpumask_empty(offlined_cpus) ||
+ num_online_cpus() != nb_available_cpus);
+
+ return err;
+}
+
+static int hotplug_tests(void)
+{
+ int err;
+ cpumask_var_t offlined_cpus;
+ int i, nb_cluster;
+ const struct cpumask **clusters;
+ char *page_buf;
+
+ err = -ENOMEM;
+ if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
+ return err;
+ /* We may have up to nb_available_cpus clusters. */
+ clusters = kmalloc_array(nb_available_cpus, sizeof(*clusters),
+ GFP_KERNEL);
+ if (!clusters)
+ goto out_free_cpus;
+ page_buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!page_buf)
+ goto out_free_clusters;
+
+ err = 0;
+ nb_cluster = find_clusters(cpu_online_mask, clusters);
+
+ /*
+ * Of course the last CPU cannot be powered down and cpu_down() should
+ * refuse doing that.
+ */
+ pr_info("Trying to turn off and on again all CPUs\n");
+ err += down_and_up_cpus(cpu_online_mask, offlined_cpus);
+
+ /*
+ * Take down CPUs by cluster this time. When the last CPU is turned
+ * off, the cluster itself should shut down.
+ */
+ for (i = 0; i < nb_cluster; ++i) {
+ int cluster_id =
+ topology_physical_package_id(cpumask_any(clusters[i]));
+ ssize_t len = cpumap_print_to_pagebuf(true, page_buf,
+ clusters[i]);
+ /* Remove trailing newline. */
+ page_buf[len - 1] = '\0';
+ pr_info("Trying to turn off and on again cluster %d "
+ "(CPUs %s)\n", cluster_id, page_buf);
+ err += down_and_up_cpus(clusters[i], offlined_cpus);
+ }
+
+ free_page((unsigned long)page_buf);
+out_free_clusters:
+ kfree(clusters);
+out_free_cpus:
+ free_cpumask_var(offlined_cpus);
+ return err;
+}
+
+static void dummy_callback(unsigned long ignored) {}
+
+static int suspend_cpu(int index, bool broadcast)
+{
+ int ret;
+
+ arch_cpu_idle_enter();
+
+ if (broadcast) {
+ /*
+ * The local timer will be shut down, we need to enter tick
+ * broadcast.
+ */
+ ret = tick_broadcast_enter();
+ if (ret) {
+ /*
+ * In the absence of hardware broadcast mechanism,
+ * this CPU might be used to broadcast wakeups, which
+ * may be why entering tick broadcast has failed.
+ * There is little the kernel can do to work around
+ * that, so enter WFI instead (idle state 0).
+ */
+ cpu_do_idle();
+ ret = 0;
+ goto out_arch_exit;
+ }
+ }
+
+ /*
+ * Replicate the common ARM cpuidle enter function
+ * (arm_enter_idle_state).
+ */
+ ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+
+ if (broadcast)
+ tick_broadcast_exit();
+
+out_arch_exit:
+ arch_cpu_idle_exit();
+
+ return ret;
+}
+
+static int suspend_test_thread(void *arg)
+{
+ int cpu = (long)arg;
+ int i, nb_suspend = 0, nb_shallow_sleep = 0, nb_err = 0;
+ struct sched_param sched_priority = { .sched_priority = MAX_RT_PRIO-1 };
+ struct cpuidle_device *dev;
+ struct cpuidle_driver *drv;
+ /* No need for an actual callback, we just want to wake up the CPU. */
+ struct timer_list wakeup_timer =
+ TIMER_INITIALIZER(dummy_callback, 0, 0);
+
+ /* Wait for the main thread to give the start signal. */
+ wait_for_completion(&suspend_threads_started);
+
+ /* Set maximum priority to preempt all other threads on this CPU. */
+ if (sched_setscheduler_nocheck(current, SCHED_FIFO, &sched_priority))
+ pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
+ cpu);
+
+ dev = this_cpu_read(cpuidle_devices);
+ drv = cpuidle_get_cpu_driver(dev);
+
+ pr_info("CPU %d entering suspend cycles, states 1 through %d\n",
+ cpu, drv->state_count - 1);
+
+ for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
+ int index;
+ /*
+ * Test all possible states, except 0 (which is usually WFI and
+ * doesn't use PSCI).
+ */
+ for (index = 1; index < drv->state_count; ++index) {
+ struct cpuidle_state *state = &drv->states[index];
+ bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
+ int ret;
+
+ /*
+ * Set the timer to wake this CPU up in some time (which
+ * should be largely sufficient for entering suspend).
+ * If the local tick is disabled when entering suspend,
+ * suspend_cpu() takes care of switching to a broadcast
+ * tick, so the timer will still wake us up.
+ */
+ mod_timer(&wakeup_timer, jiffies +
+ usecs_to_jiffies(state->target_residency));
+
+ /* IRQs must be disabled during suspend operations. */
+ local_irq_disable();
+
+ ret = suspend_cpu(index, broadcast);
+
+ /*
+ * We have woken up. Re-enable IRQs to handle any
+ * pending interrupt, do not wait until the end of the
+ * loop.
+ */
+ local_irq_enable();
+
+ if (ret == index) {
+ ++nb_suspend;
+ } else if (ret >= 0) {
+ /* We did not enter the expected state. */
+ ++nb_shallow_sleep;
+ } else {
+ pr_err("Failed to suspend CPU %d: error %d "
+ "(requested state %d, cycle %d)\n",
+ cpu, ret, index, i);
+ ++nb_err;
+ }
+ }
+ }
+
+ /*
+ * Disable the timer to make sure that the timer will not trigger
+ * later.
+ */
+ del_timer(&wakeup_timer);
+
+ if (atomic_dec_return_relaxed(&nb_active_threads) == 0)
+ complete(&suspend_threads_done);
+
+ /* Give up on RT scheduling and wait for termination. */
+ sched_priority.sched_priority = 0;
+ if (sched_setscheduler_nocheck(current, SCHED_NORMAL, &sched_priority))
+ pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
+ cpu);
+ for (;;) {
+ /* Needs to be set first to avoid missing a wakeup. */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (kthread_should_stop()) {
+ __set_current_state(TASK_RUNNING);
+ break;
+ }
+ schedule();
+ }
+
+ pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
+ cpu, nb_suspend, nb_shallow_sleep, nb_err);
+
+ return nb_err;
+}
+
+static int suspend_tests(void)
+{
+ int i, cpu, err = 0;
+ struct task_struct **threads;
+ int nb_threads = 0;
+
+ threads = kmalloc_array(nb_available_cpus, sizeof(*threads),
+ GFP_KERNEL);
+ if (!threads)
+ return -ENOMEM;
+
+ /*
+ * Stop cpuidle to prevent the idle tasks from entering a deep sleep
+ * mode, as it might interfere with the suspend threads on other CPUs.
+ * This does not prevent the suspend threads from using cpuidle (only
+ * the idle tasks check this status). Take the idle lock so that
+ * the cpuidle driver and device look-up can be carried out safely.
+ */
+ cpuidle_pause_and_lock();
+
+ for_each_online_cpu(cpu) {
+ struct task_struct *thread;
+ /* Check that cpuidle is available on that CPU. */
+ struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+
+ if (!dev || !drv) {
+ pr_warn("cpuidle not available on CPU %d, ignoring\n",
+ cpu);
+ continue;
+ }
+
+ thread = kthread_create_on_cpu(suspend_test_thread,
+ (void *)(long)cpu, cpu,
+ "psci_suspend_test");
+ if (IS_ERR(thread))
+ pr_err("Failed to create kthread on CPU %d\n", cpu);
+ else
+ threads[nb_threads++] = thread;
+ }
+
+ if (nb_threads < 1) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ atomic_set(&nb_active_threads, nb_threads);
+
+ /*
+ * Wake up the suspend threads. To avoid the main thread being preempted
+ * before all the threads have been unparked, the suspend threads will
+ * wait for the completion of suspend_threads_started.
+ */
+ for (i = 0; i < nb_threads; ++i)
+ wake_up_process(threads[i]);
+ complete_all(&suspend_threads_started);
+
+ wait_for_completion(&suspend_threads_done);
+
+
+ /* Stop and destroy all threads, get return status. */
+ for (i = 0; i < nb_threads; ++i)
+ err += kthread_stop(threads[i]);
+ out:
+ cpuidle_resume_and_unlock();
+ kfree(threads);
+ return err;
+}
+
+static int __init psci_checker(void)
+{
+ int ret;
+
+ /*
+ * Since we're in an initcall, we assume that all the CPUs that all
+ * CPUs that can be onlined have been onlined.
+ *
+ * The tests assume that hotplug is enabled but nobody else is using it,
+ * otherwise the results will be unpredictable. However, since there
+ * is no userspace yet in initcalls, that should be fine, as long as
+ * no torture test is running at the same time (see Kconfig).
+ */
+ nb_available_cpus = num_online_cpus();
+
+ /* Check PSCI operations are set up and working. */
+ ret = psci_ops_check();
+ if (ret)
+ return ret;
+
+ pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);
+
+ pr_info("Starting hotplug tests\n");
+ ret = hotplug_tests();
+ if (ret == 0)
+ pr_info("Hotplug tests passed OK\n");
+ else if (ret > 0)
+ pr_err("%d error(s) encountered in hotplug tests\n", ret);
+ else {
+ pr_err("Out of memory\n");
+ return ret;
+ }
+
+ pr_info("Starting suspend tests (%d cycles per state)\n",
+ NUM_SUSPEND_CYCLE);
+ ret = suspend_tests();
+ if (ret == 0)
+ pr_info("Suspend tests passed OK\n");
+ else if (ret > 0)
+ pr_err("%d error(s) encountered in suspend tests\n", ret);
+ else {
+ switch (ret) {
+ case -ENOMEM:
+ pr_err("Out of memory\n");
+ break;
+ case -ENODEV:
+ pr_warn("Could not start suspend tests on any CPU\n");
+ break;
+ }
+ }
+
+ pr_info("PSCI checker completed\n");
+ return ret < 0 ? ret : 0;
+}
+late_initcall(psci_checker);
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index d95c70227c05..893f953eaccf 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -28,6 +28,10 @@
#include "qcom_scm.h"
+#define SCM_HAS_CORE_CLK BIT(0)
+#define SCM_HAS_IFACE_CLK BIT(1)
+#define SCM_HAS_BUS_CLK BIT(2)
+
struct qcom_scm {
struct device *dev;
struct clk *core_clk;
@@ -323,32 +327,40 @@ EXPORT_SYMBOL(qcom_scm_is_available);
static int qcom_scm_probe(struct platform_device *pdev)
{
struct qcom_scm *scm;
+ unsigned long clks;
int ret;
scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL);
if (!scm)
return -ENOMEM;
- scm->core_clk = devm_clk_get(&pdev->dev, "core");
- if (IS_ERR(scm->core_clk)) {
- if (PTR_ERR(scm->core_clk) == -EPROBE_DEFER)
+ clks = (unsigned long)of_device_get_match_data(&pdev->dev);
+ if (clks & SCM_HAS_CORE_CLK) {
+ scm->core_clk = devm_clk_get(&pdev->dev, "core");
+ if (IS_ERR(scm->core_clk)) {
+ if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to acquire core clk\n");
return PTR_ERR(scm->core_clk);
-
- scm->core_clk = NULL;
+ }
}
- if (of_device_is_compatible(pdev->dev.of_node, "qcom,scm")) {
+ if (clks & SCM_HAS_IFACE_CLK) {
scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
if (IS_ERR(scm->iface_clk)) {
if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "failed to acquire iface clk\n");
+ dev_err(&pdev->dev,
+ "failed to acquire iface clk\n");
return PTR_ERR(scm->iface_clk);
}
+ }
+ if (clks & SCM_HAS_BUS_CLK) {
scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
if (IS_ERR(scm->bus_clk)) {
if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "failed to acquire bus clk\n");
+ dev_err(&pdev->dev,
+ "failed to acquire bus clk\n");
return PTR_ERR(scm->bus_clk);
}
}
@@ -356,7 +368,9 @@ static int qcom_scm_probe(struct platform_device *pdev)
scm->reset.ops = &qcom_scm_pas_reset_ops;
scm->reset.nr_resets = 1;
scm->reset.of_node = pdev->dev.of_node;
- reset_controller_register(&scm->reset);
+ ret = devm_reset_controller_register(&pdev->dev, &scm->reset);
+ if (ret)
+ return ret;
/* vote for max clk rate for highest performance */
ret = clk_set_rate(scm->core_clk, INT_MAX);
@@ -372,10 +386,23 @@ static int qcom_scm_probe(struct platform_device *pdev)
}
static const struct of_device_id qcom_scm_dt_match[] = {
- { .compatible = "qcom,scm-apq8064",},
- { .compatible = "qcom,scm-msm8660",},
- { .compatible = "qcom,scm-msm8960",},
- { .compatible = "qcom,scm",},
+ { .compatible = "qcom,scm-apq8064",
+ .data = (void *) SCM_HAS_CORE_CLK,
+ },
+ { .compatible = "qcom,scm-msm8660",
+ .data = (void *) SCM_HAS_CORE_CLK,
+ },
+ { .compatible = "qcom,scm-msm8960",
+ .data = (void *) SCM_HAS_CORE_CLK,
+ },
+ { .compatible = "qcom,scm-msm8996",
+ .data = NULL, /* no clocks */
+ },
+ { .compatible = "qcom,scm",
+ .data = (void *)(SCM_HAS_CORE_CLK
+ | SCM_HAS_IFACE_CLK
+ | SCM_HAS_BUS_CLK),
+ },
{}
};
diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
new file mode 100644
index 000000000000..ff2730d5c468
--- /dev/null
+++ b/drivers/firmware/tegra/Kconfig
@@ -0,0 +1,25 @@
+menu "Tegra firmware driver"
+
+config TEGRA_IVC
+ bool "Tegra IVC protocol"
+ depends on ARCH_TEGRA
+ help
+ IVC (Inter-VM Communication) protocol is part of the IPC
+ (Inter Processor Communication) framework on Tegra. It maintains the
+ data and the different commuication channels in SysRAM or RAM and
+ keeps the content is synchronization between host CPU and remote
+ processors.
+
+config TEGRA_BPMP
+ bool "Tegra BPMP driver"
+ depends on ARCH_TEGRA && TEGRA_HSP_MBOX && TEGRA_IVC
+ help
+ BPMP (Boot and Power Management Processor) is designed to off-loading
+ the PM functions which include clock/DVFS/thermal/power from the CPU.
+ It needs HSP as the HW synchronization and notification module and
+ IVC module as the message communication protocol.
+
+ This driver manages the IPC interface between host CPU and the
+ firmware running on BPMP.
+
+endmenu
diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile
new file mode 100644
index 000000000000..e34a2f79e1ad
--- /dev/null
+++ b/drivers/firmware/tegra/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_TEGRA_BPMP) += bpmp.o
+obj-$(CONFIG_TEGRA_IVC) += ivc.o
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
new file mode 100644
index 000000000000..4ff02d310868
--- /dev/null
+++ b/drivers/firmware/tegra/bpmp.c
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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/clk/tegra.h>
+#include <linux/genalloc.h>
+#include <linux/mailbox_client.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/semaphore.h>
+
+#include <soc/tegra/bpmp.h>
+#include <soc/tegra/bpmp-abi.h>
+#include <soc/tegra/ivc.h>
+
+#define MSG_ACK BIT(0)
+#define MSG_RING BIT(1)
+
+static inline struct tegra_bpmp *
+mbox_client_to_bpmp(struct mbox_client *client)
+{
+ return container_of(client, struct tegra_bpmp, mbox.client);
+}
+
+struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct tegra_bpmp *bpmp;
+ struct device_node *np;
+
+ np = of_parse_phandle(dev->of_node, "nvidia,bpmp", 0);
+ if (!np)
+ return ERR_PTR(-ENOENT);
+
+ pdev = of_find_device_by_node(np);
+ if (!pdev) {
+ bpmp = ERR_PTR(-ENODEV);
+ goto put;
+ }
+
+ bpmp = platform_get_drvdata(pdev);
+ if (!bpmp) {
+ bpmp = ERR_PTR(-EPROBE_DEFER);
+ put_device(&pdev->dev);
+ goto put;
+ }
+
+put:
+ of_node_put(np);
+ return bpmp;
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_get);
+
+void tegra_bpmp_put(struct tegra_bpmp *bpmp)
+{
+ if (bpmp)
+ put_device(bpmp->dev);
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_put);
+
+static int tegra_bpmp_channel_get_index(struct tegra_bpmp_channel *channel)
+{
+ return channel - channel->bpmp->channels;
+}
+
+static int
+tegra_bpmp_channel_get_thread_index(struct tegra_bpmp_channel *channel)
+{
+ struct tegra_bpmp *bpmp = channel->bpmp;
+ unsigned int offset, count;
+ int index;
+
+ offset = bpmp->soc->channels.thread.offset;
+ count = bpmp->soc->channels.thread.count;
+
+ index = tegra_bpmp_channel_get_index(channel);
+ if (index < 0)
+ return index;
+
+ if (index < offset || index >= offset + count)
+ return -EINVAL;
+
+ return index - offset;
+}
+
+static struct tegra_bpmp_channel *
+tegra_bpmp_channel_get_thread(struct tegra_bpmp *bpmp, unsigned int index)
+{
+ unsigned int offset = bpmp->soc->channels.thread.offset;
+ unsigned int count = bpmp->soc->channels.thread.count;
+
+ if (index >= count)
+ return NULL;
+
+ return &bpmp->channels[offset + index];
+}
+
+static struct tegra_bpmp_channel *
+tegra_bpmp_channel_get_tx(struct tegra_bpmp *bpmp)
+{
+ unsigned int offset = bpmp->soc->channels.cpu_tx.offset;
+
+ return &bpmp->channels[offset + smp_processor_id()];
+}
+
+static struct tegra_bpmp_channel *
+tegra_bpmp_channel_get_rx(struct tegra_bpmp *bpmp)
+{
+ unsigned int offset = bpmp->soc->channels.cpu_rx.offset;
+
+ return &bpmp->channels[offset];
+}
+
+static bool tegra_bpmp_message_valid(const struct tegra_bpmp_message *msg)
+{
+ return (msg->tx.size <= MSG_DATA_MIN_SZ) &&
+ (msg->rx.size <= MSG_DATA_MIN_SZ) &&
+ (msg->tx.size == 0 || msg->tx.data) &&
+ (msg->rx.size == 0 || msg->rx.data);
+}
+
+static bool tegra_bpmp_master_acked(struct tegra_bpmp_channel *channel)
+{
+ void *frame;
+
+ frame = tegra_ivc_read_get_next_frame(channel->ivc);
+ if (IS_ERR(frame)) {
+ channel->ib = NULL;
+ return false;
+ }
+
+ channel->ib = frame;
+
+ return true;
+}
+
+static int tegra_bpmp_wait_ack(struct tegra_bpmp_channel *channel)
+{
+ unsigned long timeout = channel->bpmp->soc->channels.cpu_tx.timeout;
+ ktime_t end;
+
+ end = ktime_add_us(ktime_get(), timeout);
+
+ do {
+ if (tegra_bpmp_master_acked(channel))
+ return 0;
+ } while (ktime_before(ktime_get(), end));
+
+ return -ETIMEDOUT;
+}
+
+static bool tegra_bpmp_master_free(struct tegra_bpmp_channel *channel)
+{
+ void *frame;
+
+ frame = tegra_ivc_write_get_next_frame(channel->ivc);
+ if (IS_ERR(frame)) {
+ channel->ob = NULL;
+ return false;
+ }
+
+ channel->ob = frame;
+
+ return true;
+}
+
+static int tegra_bpmp_wait_master_free(struct tegra_bpmp_channel *channel)
+{
+ unsigned long timeout = channel->bpmp->soc->channels.cpu_tx.timeout;
+ ktime_t start, now;
+
+ start = ns_to_ktime(local_clock());
+
+ do {
+ if (tegra_bpmp_master_free(channel))
+ return 0;
+
+ now = ns_to_ktime(local_clock());
+ } while (ktime_us_delta(now, start) < timeout);
+
+ return -ETIMEDOUT;
+}
+
+static ssize_t __tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
+ void *data, size_t size)
+{
+ if (data && size > 0)
+ memcpy(data, channel->ib->data, size);
+
+ return tegra_ivc_read_advance(channel->ivc);
+}
+
+static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
+ void *data, size_t size)
+{
+ struct tegra_bpmp *bpmp = channel->bpmp;
+ unsigned long flags;
+ ssize_t err;
+ int index;
+
+ index = tegra_bpmp_channel_get_thread_index(channel);
+ if (index < 0)
+ return index;
+
+ spin_lock_irqsave(&bpmp->lock, flags);
+ err = __tegra_bpmp_channel_read(channel, data, size);
+ clear_bit(index, bpmp->threaded.allocated);
+ spin_unlock_irqrestore(&bpmp->lock, flags);
+
+ up(&bpmp->threaded.lock);
+
+ return err;
+}
+
+static ssize_t __tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
+ unsigned int mrq, unsigned long flags,
+ const void *data, size_t size)
+{
+ channel->ob->code = mrq;
+ channel->ob->flags = flags;
+
+ if (data && size > 0)
+ memcpy(channel->ob->data, data, size);
+
+ return tegra_ivc_write_advance(channel->ivc);
+}
+
+static struct tegra_bpmp_channel *
+tegra_bpmp_write_threaded(struct tegra_bpmp *bpmp, unsigned int mrq,
+ const void *data, size_t size)
+{
+ unsigned long timeout = bpmp->soc->channels.thread.timeout;
+ unsigned int count = bpmp->soc->channels.thread.count;
+ struct tegra_bpmp_channel *channel;
+ unsigned long flags;
+ unsigned int index;
+ int err;
+
+ err = down_timeout(&bpmp->threaded.lock, usecs_to_jiffies(timeout));
+ if (err < 0)
+ return ERR_PTR(err);
+
+ spin_lock_irqsave(&bpmp->lock, flags);
+
+ index = find_first_zero_bit(bpmp->threaded.allocated, count);
+ if (index == count) {
+ channel = ERR_PTR(-EBUSY);
+ goto unlock;
+ }
+
+ channel = tegra_bpmp_channel_get_thread(bpmp, index);
+ if (!channel) {
+ channel = ERR_PTR(-EINVAL);
+ goto unlock;
+ }
+
+ if (!tegra_bpmp_master_free(channel)) {
+ channel = ERR_PTR(-EBUSY);
+ goto unlock;
+ }
+
+ set_bit(index, bpmp->threaded.allocated);
+
+ err = __tegra_bpmp_channel_write(channel, mrq, MSG_ACK | MSG_RING,
+ data, size);
+ if (err < 0) {
+ clear_bit(index, bpmp->threaded.allocated);
+ goto unlock;
+ }
+
+ set_bit(index, bpmp->threaded.busy);
+
+unlock:
+ spin_unlock_irqrestore(&bpmp->lock, flags);
+ return channel;
+}
+
+static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
+ unsigned int mrq, unsigned long flags,
+ const void *data, size_t size)
+{
+ int err;
+
+ err = tegra_bpmp_wait_master_free(channel);
+ if (err < 0)
+ return err;
+
+ return __tegra_bpmp_channel_write(channel, mrq, flags, data, size);
+}
+
+int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
+ struct tegra_bpmp_message *msg)
+{
+ struct tegra_bpmp_channel *channel;
+ int err;
+
+ if (WARN_ON(!irqs_disabled()))
+ return -EPERM;
+
+ if (!tegra_bpmp_message_valid(msg))
+ return -EINVAL;
+
+ channel = tegra_bpmp_channel_get_tx(bpmp);
+
+ err = tegra_bpmp_channel_write(channel, msg->mrq, MSG_ACK,
+ msg->tx.data, msg->tx.size);
+ if (err < 0)
+ return err;
+
+ err = mbox_send_message(bpmp->mbox.channel, NULL);
+ if (err < 0)
+ return err;
+
+ mbox_client_txdone(bpmp->mbox.channel, 0);
+
+ err = tegra_bpmp_wait_ack(channel);
+ if (err < 0)
+ return err;
+
+ return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size);
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_transfer_atomic);
+
+int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
+ struct tegra_bpmp_message *msg)
+{
+ struct tegra_bpmp_channel *channel;
+ unsigned long timeout;
+ int err;
+
+ if (WARN_ON(irqs_disabled()))
+ return -EPERM;
+
+ if (!tegra_bpmp_message_valid(msg))
+ return -EINVAL;
+
+ channel = tegra_bpmp_write_threaded(bpmp, msg->mrq, msg->tx.data,
+ msg->tx.size);
+ if (IS_ERR(channel))
+ return PTR_ERR(channel);
+
+ err = mbox_send_message(bpmp->mbox.channel, NULL);
+ if (err < 0)
+ return err;
+
+ mbox_client_txdone(bpmp->mbox.channel, 0);
+
+ timeout = usecs_to_jiffies(bpmp->soc->channels.thread.timeout);
+
+ err = wait_for_completion_timeout(&channel->completion, timeout);
+ if (err == 0)
+ return -ETIMEDOUT;
+
+ return tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size);
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_transfer);
+
+static struct tegra_bpmp_mrq *tegra_bpmp_find_mrq(struct tegra_bpmp *bpmp,
+ unsigned int mrq)
+{
+ struct tegra_bpmp_mrq *entry;
+
+ list_for_each_entry(entry, &bpmp->mrqs, list)
+ if (entry->mrq == mrq)
+ return entry;
+
+ return NULL;
+}
+
+static void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel,
+ int code, const void *data, size_t size)
+{
+ unsigned long flags = channel->ib->flags;
+ struct tegra_bpmp *bpmp = channel->bpmp;
+ struct tegra_bpmp_mb_data *frame;
+ int err;
+
+ if (WARN_ON(size > MSG_DATA_MIN_SZ))
+ return;
+
+ err = tegra_ivc_read_advance(channel->ivc);
+ if (WARN_ON(err < 0))
+ return;
+
+ if ((flags & MSG_ACK) == 0)
+ return;
+
+ frame = tegra_ivc_write_get_next_frame(channel->ivc);
+ if (WARN_ON(IS_ERR(frame)))
+ return;
+
+ frame->code = code;
+
+ if (data && size > 0)
+ memcpy(frame->data, data, size);
+
+ err = tegra_ivc_write_advance(channel->ivc);
+ if (WARN_ON(err < 0))
+ return;
+
+ if (flags & MSG_RING) {
+ err = mbox_send_message(bpmp->mbox.channel, NULL);
+ if (WARN_ON(err < 0))
+ return;
+
+ mbox_client_txdone(bpmp->mbox.channel, 0);
+ }
+}
+
+static void tegra_bpmp_handle_mrq(struct tegra_bpmp *bpmp,
+ unsigned int mrq,
+ struct tegra_bpmp_channel *channel)
+{
+ struct tegra_bpmp_mrq *entry;
+ u32 zero = 0;
+
+ spin_lock(&bpmp->lock);
+
+ entry = tegra_bpmp_find_mrq(bpmp, mrq);
+ if (!entry) {
+ spin_unlock(&bpmp->lock);
+ tegra_bpmp_mrq_return(channel, -EINVAL, &zero, sizeof(zero));
+ return;
+ }
+
+ entry->handler(mrq, channel, entry->data);
+
+ spin_unlock(&bpmp->lock);
+}
+
+int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
+ tegra_bpmp_mrq_handler_t handler, void *data)
+{
+ struct tegra_bpmp_mrq *entry;
+ unsigned long flags;
+
+ if (!handler)
+ return -EINVAL;
+
+ entry = devm_kzalloc(bpmp->dev, sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&bpmp->lock, flags);
+
+ entry->mrq = mrq;
+ entry->handler = handler;
+ entry->data = data;
+ list_add(&entry->list, &bpmp->mrqs);
+
+ spin_unlock_irqrestore(&bpmp->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_request_mrq);
+
+void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, void *data)
+{
+ struct tegra_bpmp_mrq *entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bpmp->lock, flags);
+
+ entry = tegra_bpmp_find_mrq(bpmp, mrq);
+ if (!entry)
+ goto unlock;
+
+ list_del(&entry->list);
+ devm_kfree(bpmp->dev, entry);
+
+unlock:
+ spin_unlock_irqrestore(&bpmp->lock, flags);
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_free_mrq);
+
+static void tegra_bpmp_mrq_handle_ping(unsigned int mrq,
+ struct tegra_bpmp_channel *channel,
+ void *data)
+{
+ struct mrq_ping_request *request;
+ struct mrq_ping_response response;
+
+ request = (struct mrq_ping_request *)channel->ib->data;
+
+ memset(&response, 0, sizeof(response));
+ response.reply = request->challenge << 1;
+
+ tegra_bpmp_mrq_return(channel, 0, &response, sizeof(response));
+}
+
+static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
+{
+ struct mrq_ping_response response;
+ struct mrq_ping_request request;
+ struct tegra_bpmp_message msg;
+ unsigned long flags;
+ ktime_t start, end;
+ int err;
+
+ memset(&request, 0, sizeof(request));
+ request.challenge = 1;
+
+ memset(&response, 0, sizeof(response));
+
+ memset(&msg, 0, sizeof(msg));
+ msg.mrq = MRQ_PING;
+ msg.tx.data = &request;
+ msg.tx.size = sizeof(request);
+ msg.rx.data = &response;
+ msg.rx.size = sizeof(response);
+
+ local_irq_save(flags);
+ start = ktime_get();
+ err = tegra_bpmp_transfer_atomic(bpmp, &msg);
+ end = ktime_get();
+ local_irq_restore(flags);
+
+ if (!err)
+ dev_dbg(bpmp->dev,
+ "ping ok: challenge: %u, response: %u, time: %lld\n",
+ request.challenge, response.reply,
+ ktime_to_us(ktime_sub(end, start)));
+
+ return err;
+}
+
+static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
+ size_t size)
+{
+ struct mrq_query_tag_request request;
+ struct tegra_bpmp_message msg;
+ unsigned long flags;
+ dma_addr_t phys;
+ void *virt;
+ int err;
+
+ virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
+ GFP_KERNEL | GFP_DMA32);
+ if (!virt)
+ return -ENOMEM;
+
+ memset(&request, 0, sizeof(request));
+ request.addr = phys;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.mrq = MRQ_QUERY_TAG;
+ msg.tx.data = &request;
+ msg.tx.size = sizeof(request);
+
+ local_irq_save(flags);
+ err = tegra_bpmp_transfer_atomic(bpmp, &msg);
+ local_irq_restore(flags);
+
+ if (err == 0)
+ strlcpy(tag, virt, size);
+
+ dma_free_coherent(bpmp->dev, MSG_DATA_MIN_SZ, virt, phys);
+
+ return err;
+}
+
+static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
+{
+ unsigned long flags = channel->ob->flags;
+
+ if ((flags & MSG_RING) == 0)
+ return;
+
+ complete(&channel->completion);
+}
+
+static void tegra_bpmp_handle_rx(struct mbox_client *client, void *data)
+{
+ struct tegra_bpmp *bpmp = mbox_client_to_bpmp(client);
+ struct tegra_bpmp_channel *channel;
+ unsigned int i, count;
+ unsigned long *busy;
+
+ channel = tegra_bpmp_channel_get_rx(bpmp);
+ count = bpmp->soc->channels.thread.count;
+ busy = bpmp->threaded.busy;
+
+ if (tegra_bpmp_master_acked(channel))
+ tegra_bpmp_handle_mrq(bpmp, channel->ib->code, channel);
+
+ spin_lock(&bpmp->lock);
+
+ for_each_set_bit(i, busy, count) {
+ struct tegra_bpmp_channel *channel;
+
+ channel = tegra_bpmp_channel_get_thread(bpmp, i);
+ if (!channel)
+ continue;
+
+ if (tegra_bpmp_master_acked(channel)) {
+ tegra_bpmp_channel_signal(channel);
+ clear_bit(i, busy);
+ }
+ }
+
+ spin_unlock(&bpmp->lock);
+}
+
+static void tegra_bpmp_ivc_notify(struct tegra_ivc *ivc, void *data)
+{
+ struct tegra_bpmp *bpmp = data;
+ int err;
+
+ if (WARN_ON(bpmp->mbox.channel == NULL))
+ return;
+
+ err = mbox_send_message(bpmp->mbox.channel, NULL);
+ if (err < 0)
+ return;
+
+ mbox_client_txdone(bpmp->mbox.channel, 0);
+}
+
+static int tegra_bpmp_channel_init(struct tegra_bpmp_channel *channel,
+ struct tegra_bpmp *bpmp,
+ unsigned int index)
+{
+ size_t message_size, queue_size;
+ unsigned int offset;
+ int err;
+
+ channel->ivc = devm_kzalloc(bpmp->dev, sizeof(*channel->ivc),
+ GFP_KERNEL);
+ if (!channel->ivc)
+ return -ENOMEM;
+
+ message_size = tegra_ivc_align(MSG_MIN_SZ);
+ queue_size = tegra_ivc_total_queue_size(message_size);
+ offset = queue_size * index;
+
+ err = tegra_ivc_init(channel->ivc, NULL,
+ bpmp->rx.virt + offset, bpmp->rx.phys + offset,
+ bpmp->tx.virt + offset, bpmp->tx.phys + offset,
+ 1, message_size, tegra_bpmp_ivc_notify,
+ bpmp);
+ if (err < 0) {
+ dev_err(bpmp->dev, "failed to setup IVC for channel %u: %d\n",
+ index, err);
+ return err;
+ }
+
+ init_completion(&channel->completion);
+ channel->bpmp = bpmp;
+
+ return 0;
+}
+
+static void tegra_bpmp_channel_reset(struct tegra_bpmp_channel *channel)
+{
+ /* reset the channel state */
+ tegra_ivc_reset(channel->ivc);
+
+ /* sync the channel state with BPMP */
+ while (tegra_ivc_notified(channel->ivc))
+ ;
+}
+
+static void tegra_bpmp_channel_cleanup(struct tegra_bpmp_channel *channel)
+{
+ tegra_ivc_cleanup(channel->ivc);
+}
+
+static int tegra_bpmp_probe(struct platform_device *pdev)
+{
+ struct tegra_bpmp_channel *channel;
+ struct tegra_bpmp *bpmp;
+ unsigned int i;
+ char tag[32];
+ size_t size;
+ int err;
+
+ bpmp = devm_kzalloc(&pdev->dev, sizeof(*bpmp), GFP_KERNEL);
+ if (!bpmp)
+ return -ENOMEM;
+
+ bpmp->soc = of_device_get_match_data(&pdev->dev);
+ bpmp->dev = &pdev->dev;
+
+ bpmp->tx.pool = of_gen_pool_get(pdev->dev.of_node, "shmem", 0);
+ if (!bpmp->tx.pool) {
+ dev_err(&pdev->dev, "TX shmem pool not found\n");
+ return -ENOMEM;
+ }
+
+ bpmp->tx.virt = gen_pool_dma_alloc(bpmp->tx.pool, 4096, &bpmp->tx.phys);
+ if (!bpmp->tx.virt) {
+ dev_err(&pdev->dev, "failed to allocate from TX pool\n");
+ return -ENOMEM;
+ }
+
+ bpmp->rx.pool = of_gen_pool_get(pdev->dev.of_node, "shmem", 1);
+ if (!bpmp->rx.pool) {
+ dev_err(&pdev->dev, "RX shmem pool not found\n");
+ err = -ENOMEM;
+ goto free_tx;
+ }
+
+ bpmp->rx.virt = gen_pool_dma_alloc(bpmp->rx.pool, 4096, &bpmp->rx.phys);
+ if (!bpmp->rx.pool) {
+ dev_err(&pdev->dev, "failed to allocate from RX pool\n");
+ err = -ENOMEM;
+ goto free_tx;
+ }
+
+ INIT_LIST_HEAD(&bpmp->mrqs);
+ spin_lock_init(&bpmp->lock);
+
+ bpmp->threaded.count = bpmp->soc->channels.thread.count;
+ sema_init(&bpmp->threaded.lock, bpmp->threaded.count);
+
+ size = BITS_TO_LONGS(bpmp->threaded.count) * sizeof(long);
+
+ bpmp->threaded.allocated = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+ if (!bpmp->threaded.allocated) {
+ err = -ENOMEM;
+ goto free_rx;
+ }
+
+ bpmp->threaded.busy = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+ if (!bpmp->threaded.busy) {
+ err = -ENOMEM;
+ goto free_rx;
+ }
+
+ bpmp->num_channels = bpmp->soc->channels.cpu_tx.count +
+ bpmp->soc->channels.thread.count +
+ bpmp->soc->channels.cpu_rx.count;
+
+ bpmp->channels = devm_kcalloc(&pdev->dev, bpmp->num_channels,
+ sizeof(*channel), GFP_KERNEL);
+ if (!bpmp->channels) {
+ err = -ENOMEM;
+ goto free_rx;
+ }
+
+ /* message channel initialization */
+ for (i = 0; i < bpmp->num_channels; i++) {
+ struct tegra_bpmp_channel *channel = &bpmp->channels[i];
+
+ err = tegra_bpmp_channel_init(channel, bpmp, i);
+ if (err < 0)
+ goto cleanup_channels;
+ }
+
+ /* mbox registration */
+ bpmp->mbox.client.dev = &pdev->dev;
+ bpmp->mbox.client.rx_callback = tegra_bpmp_handle_rx;
+ bpmp->mbox.client.tx_block = false;
+ bpmp->mbox.client.knows_txdone = false;
+
+ bpmp->mbox.channel = mbox_request_channel(&bpmp->mbox.client, 0);
+ if (IS_ERR(bpmp->mbox.channel)) {
+ err = PTR_ERR(bpmp->mbox.channel);
+ dev_err(&pdev->dev, "failed to get HSP mailbox: %d\n", err);
+ goto cleanup_channels;
+ }
+
+ /* reset message channels */
+ for (i = 0; i < bpmp->num_channels; i++) {
+ struct tegra_bpmp_channel *channel = &bpmp->channels[i];
+
+ tegra_bpmp_channel_reset(channel);
+ }
+
+ err = tegra_bpmp_request_mrq(bpmp, MRQ_PING,
+ tegra_bpmp_mrq_handle_ping, bpmp);
+ if (err < 0)
+ goto free_mbox;
+
+ err = tegra_bpmp_ping(bpmp);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to ping BPMP: %d\n", err);
+ goto free_mrq;
+ }
+
+ err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag) - 1);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
+ goto free_mrq;
+ }
+
+ dev_info(&pdev->dev, "firmware: %s\n", tag);
+
+ err = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev);
+ if (err < 0)
+ goto free_mrq;
+
+ err = tegra_bpmp_init_clocks(bpmp);
+ if (err < 0)
+ goto free_mrq;
+
+ err = tegra_bpmp_init_resets(bpmp);
+ if (err < 0)
+ goto free_mrq;
+
+ platform_set_drvdata(pdev, bpmp);
+
+ return 0;
+
+free_mrq:
+ tegra_bpmp_free_mrq(bpmp, MRQ_PING, bpmp);
+free_mbox:
+ mbox_free_channel(bpmp->mbox.channel);
+cleanup_channels:
+ while (i--)
+ tegra_bpmp_channel_cleanup(&bpmp->channels[i]);
+free_rx:
+ gen_pool_free(bpmp->rx.pool, (unsigned long)bpmp->rx.virt, 4096);
+free_tx:
+ gen_pool_free(bpmp->tx.pool, (unsigned long)bpmp->tx.virt, 4096);
+ return err;
+}
+
+static const struct tegra_bpmp_soc tegra186_soc = {
+ .channels = {
+ .cpu_tx = {
+ .offset = 0,
+ .count = 6,
+ .timeout = 60 * USEC_PER_SEC,
+ },
+ .thread = {
+ .offset = 6,
+ .count = 7,
+ .timeout = 600 * USEC_PER_SEC,
+ },
+ .cpu_rx = {
+ .offset = 13,
+ .count = 1,
+ .timeout = 0,
+ },
+ },
+ .num_resets = 193,
+};
+
+static const struct of_device_id tegra_bpmp_match[] = {
+ { .compatible = "nvidia,tegra186-bpmp", .data = &tegra186_soc },
+ { }
+};
+
+static struct platform_driver tegra_bpmp_driver = {
+ .driver = {
+ .name = "tegra-bpmp",
+ .of_match_table = tegra_bpmp_match,
+ },
+ .probe = tegra_bpmp_probe,
+};
+
+static int __init tegra_bpmp_init(void)
+{
+ return platform_driver_register(&tegra_bpmp_driver);
+}
+core_initcall(tegra_bpmp_init);
diff --git a/drivers/firmware/tegra/ivc.c b/drivers/firmware/tegra/ivc.c
new file mode 100644
index 000000000000..29ecfd815320
--- /dev/null
+++ b/drivers/firmware/tegra/ivc.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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 <soc/tegra/ivc.h>
+
+#define TEGRA_IVC_ALIGN 64
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum tegra_ivc_state {
+ /*
+ * This value is zero for backwards compatibility with services that
+ * assume channels to be initially zeroed. Such channels are in an
+ * initially valid state, but cannot be asynchronously reset, and must
+ * maintain a valid state at all times.
+ *
+ * The transmitting end can enter the established state from the sync or
+ * ack state when it observes the receiving endpoint in the ack or
+ * established state, indicating that has cleared the counters in our
+ * rx_channel.
+ */
+ TEGRA_IVC_STATE_ESTABLISHED = 0,
+
+ /*
+ * If an endpoint is observed in the sync state, the remote endpoint is
+ * allowed to clear the counters it owns asynchronously with respect to
+ * the current endpoint. Therefore, the current endpoint is no longer
+ * allowed to communicate.
+ */
+ TEGRA_IVC_STATE_SYNC,
+
+ /*
+ * When the transmitting end observes the receiving end in the sync
+ * state, it can clear the w_count and r_count and transition to the ack
+ * state. If the remote endpoint observes us in the ack state, it can
+ * return to the established state once it has cleared its counters.
+ */
+ TEGRA_IVC_STATE_ACK
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx.channel pointer, while the second is only written
+ * through the rx.channel pointer. This delineates ownership of the cache
+ * lines, which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct tegra_ivc_header {
+ union {
+ struct {
+ /* fields owned by the transmitting end */
+ u32 count;
+ u32 state;
+ };
+
+ u8 pad[TEGRA_IVC_ALIGN];
+ } tx;
+
+ union {
+ /* fields owned by the receiving end */
+ u32 count;
+ u8 pad[TEGRA_IVC_ALIGN];
+ } rx;
+};
+
+static inline void tegra_ivc_invalidate(struct tegra_ivc *ivc, dma_addr_t phys)
+{
+ if (!ivc->peer)
+ return;
+
+ dma_sync_single_for_cpu(ivc->peer, phys, TEGRA_IVC_ALIGN,
+ DMA_FROM_DEVICE);
+}
+
+static inline void tegra_ivc_flush(struct tegra_ivc *ivc, dma_addr_t phys)
+{
+ if (!ivc->peer)
+ return;
+
+ dma_sync_single_for_device(ivc->peer, phys, TEGRA_IVC_ALIGN,
+ DMA_TO_DEVICE);
+}
+
+static inline bool tegra_ivc_empty(struct tegra_ivc *ivc,
+ struct tegra_ivc_header *header)
+{
+ /*
+ * This function performs multiple checks on the same values with
+ * security implications, so create snapshots with ACCESS_ONCE() to
+ * ensure that these checks use the same values.
+ */
+ u32 tx = ACCESS_ONCE(header->tx.count);
+ u32 rx = ACCESS_ONCE(header->rx.count);
+
+ /*
+ * Perform an over-full check to prevent denial of service attacks
+ * where a server could be easily fooled into believing that there's
+ * an extremely large number of frames ready, since receivers are not
+ * expected to check for full or over-full conditions.
+ *
+ * Although the channel isn't empty, this is an invalid case caused by
+ * a potentially malicious peer, so returning empty is safer, because
+ * it gives the impression that the channel has gone silent.
+ */
+ if (tx - rx > ivc->num_frames)
+ return true;
+
+ return tx == rx;
+}
+
+static inline bool tegra_ivc_full(struct tegra_ivc *ivc,
+ struct tegra_ivc_header *header)
+{
+ u32 tx = ACCESS_ONCE(header->tx.count);
+ u32 rx = ACCESS_ONCE(header->rx.count);
+
+ /*
+ * Invalid cases where the counters indicate that the queue is over
+ * capacity also appear full.
+ */
+ return tx - rx >= ivc->num_frames;
+}
+
+static inline u32 tegra_ivc_available(struct tegra_ivc *ivc,
+ struct tegra_ivc_header *header)
+{
+ u32 tx = ACCESS_ONCE(header->tx.count);
+ u32 rx = ACCESS_ONCE(header->rx.count);
+
+ /*
+ * This function isn't expected to be used in scenarios where an
+ * over-full situation can lead to denial of service attacks. See the
+ * comment in tegra_ivc_empty() for an explanation about special
+ * over-full considerations.
+ */
+ return tx - rx;
+}
+
+static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
+{
+ ACCESS_ONCE(ivc->tx.channel->tx.count) =
+ ACCESS_ONCE(ivc->tx.channel->tx.count) + 1;
+
+ if (ivc->tx.position == ivc->num_frames - 1)
+ ivc->tx.position = 0;
+ else
+ ivc->tx.position++;
+}
+
+static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
+{
+ ACCESS_ONCE(ivc->rx.channel->rx.count) =
+ ACCESS_ONCE(ivc->rx.channel->rx.count) + 1;
+
+ if (ivc->rx.position == ivc->num_frames - 1)
+ ivc->rx.position = 0;
+ else
+ ivc->rx.position++;
+}
+
+static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
+{
+ unsigned int offset = offsetof(struct tegra_ivc_header, tx.count);
+
+ /*
+ * tx.channel->state is set locally, so it is not synchronized with
+ * state from the remote peer. The remote peer cannot reset its
+ * transmit counters until we've acknowledged its synchronization
+ * request, so no additional synchronization is required because an
+ * asynchronous transition of rx.channel->state to
+ * TEGRA_IVC_STATE_ACK is not allowed.
+ */
+ if (ivc->tx.channel->tx.state != TEGRA_IVC_STATE_ESTABLISHED)
+ return -ECONNRESET;
+
+ /*
+ * Avoid unnecessary invalidations when performing repeated accesses
+ * to an IVC channel by checking the old queue pointers first.
+ *
+ * Synchronization is only necessary when these pointers indicate
+ * empty or full.
+ */
+ if (!tegra_ivc_empty(ivc, ivc->rx.channel))
+ return 0;
+
+ tegra_ivc_invalidate(ivc, ivc->rx.phys + offset);
+
+ if (tegra_ivc_empty(ivc, ivc->rx.channel))
+ return -ENOSPC;
+
+ return 0;
+}
+
+static inline int tegra_ivc_check_write(struct tegra_ivc *ivc)
+{
+ unsigned int offset = offsetof(struct tegra_ivc_header, rx.count);
+
+ if (ivc->tx.channel->tx.state != TEGRA_IVC_STATE_ESTABLISHED)
+ return -ECONNRESET;
+
+ if (!tegra_ivc_full(ivc, ivc->tx.channel))
+ return 0;
+
+ tegra_ivc_invalidate(ivc, ivc->tx.phys + offset);
+
+ if (tegra_ivc_full(ivc, ivc->tx.channel))
+ return -ENOSPC;
+
+ return 0;
+}
+
+static void *tegra_ivc_frame_virt(struct tegra_ivc *ivc,
+ struct tegra_ivc_header *header,
+ unsigned int frame)
+{
+ if (WARN_ON(frame >= ivc->num_frames))
+ return ERR_PTR(-EINVAL);
+
+ return (void *)(header + 1) + ivc->frame_size * frame;
+}
+
+static inline dma_addr_t tegra_ivc_frame_phys(struct tegra_ivc *ivc,
+ dma_addr_t phys,
+ unsigned int frame)
+{
+ unsigned long offset;
+
+ offset = sizeof(struct tegra_ivc_header) + ivc->frame_size * frame;
+
+ return phys + offset;
+}
+
+static inline void tegra_ivc_invalidate_frame(struct tegra_ivc *ivc,
+ dma_addr_t phys,
+ unsigned int frame,
+ unsigned int offset,
+ size_t size)
+{
+ if (!ivc->peer || WARN_ON(frame >= ivc->num_frames))
+ return;
+
+ phys = tegra_ivc_frame_phys(ivc, phys, frame) + offset;
+
+ dma_sync_single_for_cpu(ivc->peer, phys, size, DMA_FROM_DEVICE);
+}
+
+static inline void tegra_ivc_flush_frame(struct tegra_ivc *ivc,
+ dma_addr_t phys,
+ unsigned int frame,
+ unsigned int offset,
+ size_t size)
+{
+ if (!ivc->peer || WARN_ON(frame >= ivc->num_frames))
+ return;
+
+ phys = tegra_ivc_frame_phys(ivc, phys, frame) + offset;
+
+ dma_sync_single_for_device(ivc->peer, phys, size, DMA_TO_DEVICE);
+}
+
+/* directly peek at the next frame rx'ed */
+void *tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc)
+{
+ int err;
+
+ if (WARN_ON(ivc == NULL))
+ return ERR_PTR(-EINVAL);
+
+ err = tegra_ivc_check_read(ivc);
+ if (err < 0)
+ return ERR_PTR(err);
+
+ /*
+ * Order observation of ivc->rx.position potentially indicating new
+ * data before data read.
+ */
+ smp_rmb();
+
+ tegra_ivc_invalidate_frame(ivc, ivc->rx.phys, ivc->rx.position, 0,
+ ivc->frame_size);
+
+ return tegra_ivc_frame_virt(ivc, ivc->rx.channel, ivc->rx.position);
+}
+EXPORT_SYMBOL(tegra_ivc_read_get_next_frame);
+
+int tegra_ivc_read_advance(struct tegra_ivc *ivc)
+{
+ unsigned int rx = offsetof(struct tegra_ivc_header, rx.count);
+ unsigned int tx = offsetof(struct tegra_ivc_header, tx.count);
+ int err;
+
+ /*
+ * No read barriers or synchronization here: the caller is expected to
+ * have already observed the channel non-empty. This check is just to
+ * catch programming errors.
+ */
+ err = tegra_ivc_check_read(ivc);
+ if (err < 0)
+ return err;
+
+ tegra_ivc_advance_rx(ivc);
+
+ tegra_ivc_flush(ivc, ivc->rx.phys + rx);
+
+ /*
+ * Ensure our write to ivc->rx.position occurs before our read from
+ * ivc->tx.position.
+ */
+ smp_mb();
+
+ /*
+ * Notify only upon transition from full to non-full. The available
+ * count can only asynchronously increase, so the worst possible
+ * side-effect will be a spurious notification.
+ */
+ tegra_ivc_invalidate(ivc, ivc->rx.phys + tx);
+
+ if (tegra_ivc_available(ivc, ivc->rx.channel) == ivc->num_frames - 1)
+ ivc->notify(ivc, ivc->notify_data);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_ivc_read_advance);
+
+/* directly poke at the next frame to be tx'ed */
+void *tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc)
+{
+ int err;
+
+ err = tegra_ivc_check_write(ivc);
+ if (err < 0)
+ return ERR_PTR(err);
+
+ return tegra_ivc_frame_virt(ivc, ivc->tx.channel, ivc->tx.position);
+}
+EXPORT_SYMBOL(tegra_ivc_write_get_next_frame);
+
+/* advance the tx buffer */
+int tegra_ivc_write_advance(struct tegra_ivc *ivc)
+{
+ unsigned int tx = offsetof(struct tegra_ivc_header, tx.count);
+ unsigned int rx = offsetof(struct tegra_ivc_header, rx.count);
+ int err;
+
+ err = tegra_ivc_check_write(ivc);
+ if (err < 0)
+ return err;
+
+ tegra_ivc_flush_frame(ivc, ivc->tx.phys, ivc->tx.position, 0,
+ ivc->frame_size);
+
+ /*
+ * Order any possible stores to the frame before update of
+ * ivc->tx.position.
+ */
+ smp_wmb();
+
+ tegra_ivc_advance_tx(ivc);
+ tegra_ivc_flush(ivc, ivc->tx.phys + tx);
+
+ /*
+ * Ensure our write to ivc->tx.position occurs before our read from
+ * ivc->rx.position.
+ */
+ smp_mb();
+
+ /*
+ * Notify only upon transition from empty to non-empty. The available
+ * count can only asynchronously decrease, so the worst possible
+ * side-effect will be a spurious notification.
+ */
+ tegra_ivc_invalidate(ivc, ivc->tx.phys + rx);
+
+ if (tegra_ivc_available(ivc, ivc->tx.channel) == 1)
+ ivc->notify(ivc, ivc->notify_data);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_ivc_write_advance);
+
+void tegra_ivc_reset(struct tegra_ivc *ivc)
+{
+ unsigned int offset = offsetof(struct tegra_ivc_header, tx.count);
+
+ ivc->tx.channel->tx.state = TEGRA_IVC_STATE_SYNC;
+ tegra_ivc_flush(ivc, ivc->tx.phys + offset);
+ ivc->notify(ivc, ivc->notify_data);
+}
+EXPORT_SYMBOL(tegra_ivc_reset);
+
+/*
+ * =======================================================
+ * IVC State Transition Table - see tegra_ivc_notified()
+ * =======================================================
+ *
+ * local remote action
+ * ----- ------ -----------------------------------
+ * SYNC EST <none>
+ * SYNC ACK reset counters; move to EST; notify
+ * SYNC SYNC reset counters; move to ACK; notify
+ * ACK EST move to EST; notify
+ * ACK ACK move to EST; notify
+ * ACK SYNC reset counters; move to ACK; notify
+ * EST EST <none>
+ * EST ACK <none>
+ * EST SYNC reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+
+int tegra_ivc_notified(struct tegra_ivc *ivc)
+{
+ unsigned int offset = offsetof(struct tegra_ivc_header, tx.count);
+ enum tegra_ivc_state state;
+
+ /* Copy the receiver's state out of shared memory. */
+ tegra_ivc_invalidate(ivc, ivc->rx.phys + offset);
+ state = ACCESS_ONCE(ivc->rx.channel->tx.state);
+
+ if (state == TEGRA_IVC_STATE_SYNC) {
+ offset = offsetof(struct tegra_ivc_header, tx.count);
+
+ /*
+ * Order observation of TEGRA_IVC_STATE_SYNC before stores
+ * clearing tx.channel.
+ */
+ smp_rmb();
+
+ /*
+ * Reset tx.channel counters. The remote end is in the SYNC
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx.channel->tx.count = 0;
+ ivc->rx.channel->rx.count = 0;
+
+ ivc->tx.position = 0;
+ ivc->rx.position = 0;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ smp_wmb();
+
+ /*
+ * Move to ACK state. We have just cleared our counters, so it
+ * is now safe for the remote end to start using these values.
+ */
+ ivc->tx.channel->tx.state = TEGRA_IVC_STATE_ACK;
+ tegra_ivc_flush(ivc, ivc->tx.phys + offset);
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc, ivc->notify_data);
+
+ } else if (ivc->tx.channel->tx.state == TEGRA_IVC_STATE_SYNC &&
+ state == TEGRA_IVC_STATE_ACK) {
+ offset = offsetof(struct tegra_ivc_header, tx.count);
+
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ smp_rmb();
+
+ /*
+ * Reset tx.channel counters. The remote end is in the ACK
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx.channel->tx.count = 0;
+ ivc->rx.channel->rx.count = 0;
+
+ ivc->tx.position = 0;
+ ivc->rx.position = 0;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ smp_wmb();
+
+ /*
+ * Move to ESTABLISHED state. We know that the remote end has
+ * already cleared its counters, so it is safe to start
+ * writing/reading on this channel.
+ */
+ ivc->tx.channel->tx.state = TEGRA_IVC_STATE_ESTABLISHED;
+ tegra_ivc_flush(ivc, ivc->tx.phys + offset);
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc, ivc->notify_data);
+
+ } else if (ivc->tx.channel->tx.state == TEGRA_IVC_STATE_ACK) {
+ offset = offsetof(struct tegra_ivc_header, tx.count);
+
+ /*
+ * At this point, we have observed the peer to be in either
+ * the ACK or ESTABLISHED state. Next, order observation of
+ * peer state before storing to tx.channel.
+ */
+ smp_rmb();
+
+ /*
+ * Move to ESTABLISHED state. We know that we have previously
+ * cleared our counters, and we know that the remote end has
+ * cleared its counters, so it is safe to start writing/reading
+ * on this channel.
+ */
+ ivc->tx.channel->tx.state = TEGRA_IVC_STATE_ESTABLISHED;
+ tegra_ivc_flush(ivc, ivc->tx.phys + offset);
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc, ivc->notify_data);
+
+ } else {
+ /*
+ * There is no need to handle any further action. Either the
+ * channel is already fully established, or we are waiting for
+ * the remote end to catch up with our current state. Refer
+ * to the diagram in "IVC State Transition Table" above.
+ */
+ }
+
+ if (ivc->tx.channel->tx.state != TEGRA_IVC_STATE_ESTABLISHED)
+ return -EAGAIN;
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_ivc_notified);
+
+size_t tegra_ivc_align(size_t size)
+{
+ return ALIGN(size, TEGRA_IVC_ALIGN);
+}
+EXPORT_SYMBOL(tegra_ivc_align);
+
+unsigned tegra_ivc_total_queue_size(unsigned queue_size)
+{
+ if (!IS_ALIGNED(queue_size, TEGRA_IVC_ALIGN)) {
+ pr_err("%s: queue_size (%u) must be %u-byte aligned\n",
+ __func__, queue_size, TEGRA_IVC_ALIGN);
+ return 0;
+ }
+
+ return queue_size + sizeof(struct tegra_ivc_header);
+}
+EXPORT_SYMBOL(tegra_ivc_total_queue_size);
+
+static int tegra_ivc_check_params(unsigned long rx, unsigned long tx,
+ unsigned int num_frames, size_t frame_size)
+{
+ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct tegra_ivc_header, tx.count),
+ TEGRA_IVC_ALIGN));
+ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct tegra_ivc_header, rx.count),
+ TEGRA_IVC_ALIGN));
+ BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct tegra_ivc_header),
+ TEGRA_IVC_ALIGN));
+
+ if ((uint64_t)num_frames * (uint64_t)frame_size >= 0x100000000UL) {
+ pr_err("num_frames * frame_size overflows\n");
+ return -EINVAL;
+ }
+
+ if (!IS_ALIGNED(frame_size, TEGRA_IVC_ALIGN)) {
+ pr_err("frame size not adequately aligned: %zu\n", frame_size);
+ return -EINVAL;
+ }
+
+ /*
+ * The headers must at least be aligned enough for counters
+ * to be accessed atomically.
+ */
+ if (!IS_ALIGNED(rx, TEGRA_IVC_ALIGN)) {
+ pr_err("IVC channel start not aligned: %#lx\n", rx);
+ return -EINVAL;
+ }
+
+ if (!IS_ALIGNED(tx, TEGRA_IVC_ALIGN)) {
+ pr_err("IVC channel start not aligned: %#lx\n", tx);
+ return -EINVAL;
+ }
+
+ if (rx < tx) {
+ if (rx + frame_size * num_frames > tx) {
+ pr_err("queue regions overlap: %#lx + %zx > %#lx\n",
+ rx, frame_size * num_frames, tx);
+ return -EINVAL;
+ }
+ } else {
+ if (tx + frame_size * num_frames > rx) {
+ pr_err("queue regions overlap: %#lx + %zx > %#lx\n",
+ tx, frame_size * num_frames, rx);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx,
+ dma_addr_t rx_phys, void *tx, dma_addr_t tx_phys,
+ unsigned int num_frames, size_t frame_size,
+ void (*notify)(struct tegra_ivc *ivc, void *data),
+ void *data)
+{
+ size_t queue_size;
+ int err;
+
+ if (WARN_ON(!ivc || !notify))
+ return -EINVAL;
+
+ /*
+ * All sizes that can be returned by communication functions should
+ * fit in an int.
+ */
+ if (frame_size > INT_MAX)
+ return -E2BIG;
+
+ err = tegra_ivc_check_params((unsigned long)rx, (unsigned long)tx,
+ num_frames, frame_size);
+ if (err < 0)
+ return err;
+
+ queue_size = tegra_ivc_total_queue_size(num_frames * frame_size);
+
+ if (peer) {
+ ivc->rx.phys = dma_map_single(peer, rx, queue_size,
+ DMA_BIDIRECTIONAL);
+ if (ivc->rx.phys == DMA_ERROR_CODE)
+ return -ENOMEM;
+
+ ivc->tx.phys = dma_map_single(peer, tx, queue_size,
+ DMA_BIDIRECTIONAL);
+ if (ivc->tx.phys == DMA_ERROR_CODE) {
+ dma_unmap_single(peer, ivc->rx.phys, queue_size,
+ DMA_BIDIRECTIONAL);
+ return -ENOMEM;
+ }
+ } else {
+ ivc->rx.phys = rx_phys;
+ ivc->tx.phys = tx_phys;
+ }
+
+ ivc->rx.channel = rx;
+ ivc->tx.channel = tx;
+ ivc->peer = peer;
+ ivc->notify = notify;
+ ivc->notify_data = data;
+ ivc->frame_size = frame_size;
+ ivc->num_frames = num_frames;
+
+ /*
+ * These values aren't necessarily correct until the channel has been
+ * reset.
+ */
+ ivc->tx.position = 0;
+ ivc->rx.position = 0;
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_ivc_init);
+
+void tegra_ivc_cleanup(struct tegra_ivc *ivc)
+{
+ if (ivc->peer) {
+ size_t size = tegra_ivc_total_queue_size(ivc->num_frames *
+ ivc->frame_size);
+
+ dma_unmap_single(ivc->peer, ivc->rx.phys, size,
+ DMA_BIDIRECTIONAL);
+ dma_unmap_single(ivc->peer, ivc->tx.phys, size,
+ DMA_BIDIRECTIONAL);
+ }
+}
+EXPORT_SYMBOL(tegra_ivc_cleanup);
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
new file mode 100644
index 000000000000..874ff32db366
--- /dev/null
+++ b/drivers/firmware/ti_sci.c
@@ -0,0 +1,1991 @@
+/*
+ * Texas Instruments System Control Interface Protocol Driver
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * 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 "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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/bitmap.h>
+#include <linux/debugfs.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <linux/soc/ti/ti-msgmgr.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/reboot.h>
+
+#include "ti_sci.h"
+
+/* List of all TI SCI devices active in system */
+static LIST_HEAD(ti_sci_list);
+/* Protection for the entire list */
+static DEFINE_MUTEX(ti_sci_list_mutex);
+
+/**
+ * struct ti_sci_xfer - Structure representing a message flow
+ * @tx_message: Transmit message
+ * @rx_len: Receive message length
+ * @xfer_buf: Preallocated buffer to store receive message
+ * Since we work with request-ACK protocol, we can
+ * reuse the same buffer for the rx path as we
+ * use for the tx path.
+ * @done: completion event
+ */
+struct ti_sci_xfer {
+ struct ti_msgmgr_message tx_message;
+ u8 rx_len;
+ u8 *xfer_buf;
+ struct completion done;
+};
+
+/**
+ * struct ti_sci_xfers_info - Structure to manage transfer information
+ * @sem_xfer_count: Counting Semaphore for managing max simultaneous
+ * Messages.
+ * @xfer_block: Preallocated Message array
+ * @xfer_alloc_table: Bitmap table for allocated messages.
+ * Index of this bitmap table is also used for message
+ * sequence identifier.
+ * @xfer_lock: Protection for message allocation
+ */
+struct ti_sci_xfers_info {
+ struct semaphore sem_xfer_count;
+ struct ti_sci_xfer *xfer_block;
+ unsigned long *xfer_alloc_table;
+ /* protect transfer allocation */
+ spinlock_t xfer_lock;
+};
+
+/**
+ * struct ti_sci_desc - Description of SoC integration
+ * @host_id: Host identifier representing the compute entity
+ * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
+ * @max_msgs: Maximum number of messages that can be pending
+ * simultaneously in the system
+ * @max_msg_size: Maximum size of data per message that can be handled.
+ */
+struct ti_sci_desc {
+ u8 host_id;
+ int max_rx_timeout_ms;
+ int max_msgs;
+ int max_msg_size;
+};
+
+/**
+ * struct ti_sci_info - Structure representing a TI SCI instance
+ * @dev: Device pointer
+ * @desc: SoC description for this instance
+ * @nb: Reboot Notifier block
+ * @d: Debugfs file entry
+ * @debug_region: Memory region where the debug message are available
+ * @debug_region_size: Debug region size
+ * @debug_buffer: Buffer allocated to copy debug messages.
+ * @handle: Instance of TI SCI handle to send to clients.
+ * @cl: Mailbox Client
+ * @chan_tx: Transmit mailbox channel
+ * @chan_rx: Receive mailbox channel
+ * @minfo: Message info
+ * @node: list head
+ * @users: Number of users of this instance
+ */
+struct ti_sci_info {
+ struct device *dev;
+ struct notifier_block nb;
+ const struct ti_sci_desc *desc;
+ struct dentry *d;
+ void __iomem *debug_region;
+ char *debug_buffer;
+ size_t debug_region_size;
+ struct ti_sci_handle handle;
+ struct mbox_client cl;
+ struct mbox_chan *chan_tx;
+ struct mbox_chan *chan_rx;
+ struct ti_sci_xfers_info minfo;
+ struct list_head node;
+ /* protected by ti_sci_list_mutex */
+ int users;
+
+};
+
+#define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl)
+#define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
+#define reboot_to_ti_sci_info(n) container_of(n, struct ti_sci_info, nb)
+
+#ifdef CONFIG_DEBUG_FS
+
+/**
+ * ti_sci_debug_show() - Helper to dump the debug log
+ * @s: sequence file pointer
+ * @unused: unused.
+ *
+ * Return: 0
+ */
+static int ti_sci_debug_show(struct seq_file *s, void *unused)
+{
+ struct ti_sci_info *info = s->private;
+
+ memcpy_fromio(info->debug_buffer, info->debug_region,
+ info->debug_region_size);
+ /*
+ * We don't trust firmware to leave NULL terminated last byte (hence
+ * we have allocated 1 extra 0 byte). Since we cannot guarantee any
+ * specific data format for debug messages, We just present the data
+ * in the buffer as is - we expect the messages to be self explanatory.
+ */
+ seq_puts(s, info->debug_buffer);
+ return 0;
+}
+
+/**
+ * ti_sci_debug_open() - debug file open
+ * @inode: inode pointer
+ * @file: file pointer
+ *
+ * Return: result of single_open
+ */
+static int ti_sci_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ti_sci_debug_show, inode->i_private);
+}
+
+/* log file operations */
+static const struct file_operations ti_sci_debug_fops = {
+ .open = ti_sci_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/**
+ * ti_sci_debugfs_create() - Create log debug file
+ * @pdev: platform device pointer
+ * @info: Pointer to SCI entity information
+ *
+ * Return: 0 if all went fine, else corresponding error.
+ */
+static int ti_sci_debugfs_create(struct platform_device *pdev,
+ struct ti_sci_info *info)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ char debug_name[50] = "ti_sci_debug@";
+
+ /* Debug region is optional */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "debug_messages");
+ info->debug_region = devm_ioremap_resource(dev, res);
+ if (IS_ERR(info->debug_region))
+ return 0;
+ info->debug_region_size = resource_size(res);
+
+ info->debug_buffer = devm_kcalloc(dev, info->debug_region_size + 1,
+ sizeof(char), GFP_KERNEL);
+ if (!info->debug_buffer)
+ return -ENOMEM;
+ /* Setup NULL termination */
+ info->debug_buffer[info->debug_region_size] = 0;
+
+ info->d = debugfs_create_file(strncat(debug_name, dev_name(dev),
+ sizeof(debug_name)),
+ 0444, NULL, info, &ti_sci_debug_fops);
+ if (IS_ERR(info->d))
+ return PTR_ERR(info->d);
+
+ dev_dbg(dev, "Debug region => %p, size = %zu bytes, resource: %pr\n",
+ info->debug_region, info->debug_region_size, res);
+ return 0;
+}
+
+/**
+ * ti_sci_debugfs_destroy() - clean up log debug file
+ * @pdev: platform device pointer
+ * @info: Pointer to SCI entity information
+ */
+static void ti_sci_debugfs_destroy(struct platform_device *pdev,
+ struct ti_sci_info *info)
+{
+ if (IS_ERR(info->debug_region))
+ return;
+
+ debugfs_remove(info->d);
+}
+#else /* CONFIG_DEBUG_FS */
+static inline int ti_sci_debugfs_create(struct platform_device *dev,
+ struct ti_sci_info *info)
+{
+ return 0;
+}
+
+static inline void ti_sci_debugfs_destroy(struct platform_device *dev,
+ struct ti_sci_info *info)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
+
+/**
+ * ti_sci_dump_header_dbg() - Helper to dump a message header.
+ * @dev: Device pointer corresponding to the SCI entity
+ * @hdr: pointer to header.
+ */
+static inline void ti_sci_dump_header_dbg(struct device *dev,
+ struct ti_sci_msg_hdr *hdr)
+{
+ dev_dbg(dev, "MSGHDR:type=0x%04x host=0x%02x seq=0x%02x flags=0x%08x\n",
+ hdr->type, hdr->host, hdr->seq, hdr->flags);
+}
+
+/**
+ * ti_sci_rx_callback() - mailbox client callback for receive messages
+ * @cl: client pointer
+ * @m: mailbox message
+ *
+ * Processes one received message to appropriate transfer information and
+ * signals completion of the transfer.
+ *
+ * NOTE: This function will be invoked in IRQ context, hence should be
+ * as optimal as possible.
+ */
+static void ti_sci_rx_callback(struct mbox_client *cl, void *m)
+{
+ struct ti_sci_info *info = cl_to_ti_sci_info(cl);
+ struct device *dev = info->dev;
+ struct ti_sci_xfers_info *minfo = &info->minfo;
+ struct ti_msgmgr_message *mbox_msg = m;
+ struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)mbox_msg->buf;
+ struct ti_sci_xfer *xfer;
+ u8 xfer_id;
+
+ xfer_id = hdr->seq;
+
+ /*
+ * Are we even expecting this?
+ * NOTE: barriers were implicit in locks used for modifying the bitmap
+ */
+ if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
+ dev_err(dev, "Message for %d is not expected!\n", xfer_id);
+ return;
+ }
+
+ xfer = &minfo->xfer_block[xfer_id];
+
+ /* Is the message of valid length? */
+ if (mbox_msg->len > info->desc->max_msg_size) {
+ dev_err(dev, "Unable to handle %d xfer(max %d)\n",
+ mbox_msg->len, info->desc->max_msg_size);
+ ti_sci_dump_header_dbg(dev, hdr);
+ return;
+ }
+ if (mbox_msg->len < xfer->rx_len) {
+ dev_err(dev, "Recv xfer %d < expected %d length\n",
+ mbox_msg->len, xfer->rx_len);
+ ti_sci_dump_header_dbg(dev, hdr);
+ return;
+ }
+
+ ti_sci_dump_header_dbg(dev, hdr);
+ /* Take a copy to the rx buffer.. */
+ memcpy(xfer->xfer_buf, mbox_msg->buf, xfer->rx_len);
+ complete(&xfer->done);
+}
+
+/**
+ * ti_sci_get_one_xfer() - Allocate one message
+ * @info: Pointer to SCI entity information
+ * @msg_type: Message type
+ * @msg_flags: Flag to set for the message
+ * @tx_message_size: transmit message size
+ * @rx_message_size: receive message size
+ *
+ * Helper function which is used by various command functions that are
+ * exposed to clients of this driver for allocating a message traffic event.
+ *
+ * This function can sleep depending on pending requests already in the system
+ * for the SCI entity. Further, this also holds a spinlock to maintain integrity
+ * of internal data structures.
+ *
+ * Return: 0 if all went fine, else corresponding error.
+ */
+static struct ti_sci_xfer *ti_sci_get_one_xfer(struct ti_sci_info *info,
+ u16 msg_type, u32 msg_flags,
+ size_t tx_message_size,
+ size_t rx_message_size)
+{
+ struct ti_sci_xfers_info *minfo = &info->minfo;
+ struct ti_sci_xfer *xfer;
+ struct ti_sci_msg_hdr *hdr;
+ unsigned long flags;
+ unsigned long bit_pos;
+ u8 xfer_id;
+ int ret;
+ int timeout;
+
+ /* Ensure we have sane transfer sizes */
+ if (rx_message_size > info->desc->max_msg_size ||
+ tx_message_size > info->desc->max_msg_size ||
+ rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr))
+ return ERR_PTR(-ERANGE);
+
+ /*
+ * Ensure we have only controlled number of pending messages.
+ * Ideally, we might just have to wait a single message, be
+ * conservative and wait 5 times that..
+ */
+ timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms) * 5;
+ ret = down_timeout(&minfo->sem_xfer_count, timeout);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ /* Keep the locked section as small as possible */
+ spin_lock_irqsave(&minfo->xfer_lock, flags);
+ bit_pos = find_first_zero_bit(minfo->xfer_alloc_table,
+ info->desc->max_msgs);
+ set_bit(bit_pos, minfo->xfer_alloc_table);
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+ /*
+ * We already ensured in probe that we can have max messages that can
+ * fit in hdr.seq - NOTE: this improves access latencies
+ * to predictable O(1) access, BUT, it opens us to risk if
+ * remote misbehaves with corrupted message sequence responses.
+ * If that happens, we are going to be messed up anyways..
+ */
+ xfer_id = (u8)bit_pos;
+
+ xfer = &minfo->xfer_block[xfer_id];
+
+ hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
+ xfer->tx_message.len = tx_message_size;
+ xfer->rx_len = (u8)rx_message_size;
+
+ reinit_completion(&xfer->done);
+
+ hdr->seq = xfer_id;
+ hdr->type = msg_type;
+ hdr->host = info->desc->host_id;
+ hdr->flags = msg_flags;
+
+ return xfer;
+}
+
+/**
+ * ti_sci_put_one_xfer() - Release a message
+ * @minfo: transfer info pointer
+ * @xfer: message that was reserved by ti_sci_get_one_xfer
+ *
+ * This holds a spinlock to maintain integrity of internal data structures.
+ */
+static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
+ struct ti_sci_xfer *xfer)
+{
+ unsigned long flags;
+ struct ti_sci_msg_hdr *hdr;
+ u8 xfer_id;
+
+ hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
+ xfer_id = hdr->seq;
+
+ /*
+ * Keep the locked section as small as possible
+ * NOTE: we might escape with smp_mb and no lock here..
+ * but just be conservative and symmetric.
+ */
+ spin_lock_irqsave(&minfo->xfer_lock, flags);
+ clear_bit(xfer_id, minfo->xfer_alloc_table);
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+ /* Increment the count for the next user to get through */
+ up(&minfo->sem_xfer_count);
+}
+
+/**
+ * ti_sci_do_xfer() - Do one transfer
+ * @info: Pointer to SCI entity information
+ * @xfer: Transfer to initiate and wait for response
+ *
+ * Return: -ETIMEDOUT in case of no response, if transmit error,
+ * return corresponding error, else if all goes well,
+ * return 0.
+ */
+static inline int ti_sci_do_xfer(struct ti_sci_info *info,
+ struct ti_sci_xfer *xfer)
+{
+ int ret;
+ int timeout;
+ struct device *dev = info->dev;
+
+ ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
+ if (ret < 0)
+ return ret;
+
+ ret = 0;
+
+ /* And we wait for the response. */
+ timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
+ if (!wait_for_completion_timeout(&xfer->done, timeout)) {
+ dev_err(dev, "Mbox timedout in resp(caller: %pF)\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+ }
+ /*
+ * NOTE: we might prefer not to need the mailbox ticker to manage the
+ * transfer queueing since the protocol layer queues things by itself.
+ * Unfortunately, we have to kick the mailbox framework after we have
+ * received our message.
+ */
+ mbox_client_txdone(info->chan_tx, ret);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
+ * @info: Pointer to SCI entity information
+ *
+ * Updates the SCI information in the internal data structure.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_get_revision(struct ti_sci_info *info)
+{
+ struct device *dev = info->dev;
+ struct ti_sci_handle *handle = &info->handle;
+ struct ti_sci_version_info *ver = &handle->version;
+ struct ti_sci_msg_resp_version *rev_info;
+ struct ti_sci_xfer *xfer;
+ int ret;
+
+ /* No need to setup flags since it is expected to respond */
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_VERSION,
+ 0x0, sizeof(struct ti_sci_msg_hdr),
+ sizeof(*rev_info));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+
+ rev_info = (struct ti_sci_msg_resp_version *)xfer->xfer_buf;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ ver->abi_major = rev_info->abi_major;
+ ver->abi_minor = rev_info->abi_minor;
+ ver->firmware_revision = rev_info->firmware_revision;
+ strncpy(ver->firmware_description, rev_info->firmware_description,
+ sizeof(ver->firmware_description));
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+ return ret;
+}
+
+/**
+ * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
+ * @r: pointer to response buffer
+ *
+ * Return: true if the response was an ACK, else returns false.
+ */
+static inline bool ti_sci_is_response_ack(void *r)
+{
+ struct ti_sci_msg_hdr *hdr = r;
+
+ return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
+}
+
+/**
+ * ti_sci_set_device_state() - Set device state helper
+ * @handle: pointer to TI SCI handle
+ * @id: Device identifier
+ * @flags: flags to setup for the device
+ * @state: State to move the device to
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
+ u32 id, u32 flags, u8 state)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_set_device_state *req;
+ struct ti_sci_msg_hdr *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
+ flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
+ req->id = id;
+ req->state = state;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+ ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_get_device_state() - Get device state helper
+ * @handle: Handle to the device
+ * @id: Device Identifier
+ * @clcnt: Pointer to Context Loss Count
+ * @resets: pointer to resets
+ * @p_state: pointer to p_state
+ * @c_state: pointer to c_state
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
+ u32 id, u32 *clcnt, u32 *resets,
+ u8 *p_state, u8 *c_state)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_get_device_state *req;
+ struct ti_sci_msg_resp_get_device_state *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ if (!clcnt && !resets && !p_state && !c_state)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ /* Response is expected, so need of any flags */
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
+ 0, sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_get_device_state *)xfer->xfer_buf;
+ req->id = id;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_resp_get_device_state *)xfer->xfer_buf;
+ if (!ti_sci_is_response_ack(resp)) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ if (clcnt)
+ *clcnt = resp->context_loss_count;
+ if (resets)
+ *resets = resp->resets;
+ if (p_state)
+ *p_state = resp->programmed_state;
+ if (c_state)
+ *c_state = resp->current_state;
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_get_device() - command to request for device managed by TISCI
+ * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * NOTE: The request is for exclusive access for the processor.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
+{
+ return ti_sci_set_device_state(handle, id,
+ MSG_FLAG_DEVICE_EXCLUSIVE,
+ MSG_DEVICE_SW_STATE_ON);
+}
+
+/**
+ * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
+ * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
+{
+ return ti_sci_set_device_state(handle, id,
+ MSG_FLAG_DEVICE_EXCLUSIVE,
+ MSG_DEVICE_SW_STATE_RETENTION);
+}
+
+/**
+ * ti_sci_cmd_put_device() - command to release a device managed by TISCI
+ * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
+{
+ return ti_sci_set_device_state(handle, id,
+ 0, MSG_DEVICE_SW_STATE_AUTO_OFF);
+}
+
+/**
+ * ti_sci_cmd_dev_is_valid() - Is the device valid
+ * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * @id: Device Identifier
+ *
+ * Return: 0 if all went fine and the device ID is valid, else return
+ * appropriate error.
+ */
+static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id)
+{
+ u8 unused;
+
+ /* check the device state which will also tell us if the ID is valid */
+ return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
+}
+
+/**
+ * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
+ * @handle: Pointer to TISCI handle
+ * @id: Device Identifier
+ * @count: Pointer to Context Loss counter to populate
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id,
+ u32 *count)
+{
+ return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
+}
+
+/**
+ * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
+ * @handle: Pointer to TISCI handle
+ * @id: Device Identifier
+ * @r_state: true if requested to be idle
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
+ bool *r_state)
+{
+ int ret;
+ u8 state;
+
+ if (!r_state)
+ return -EINVAL;
+
+ ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
+ if (ret)
+ return ret;
+
+ *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
+
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
+ * @handle: Pointer to TISCI handle
+ * @id: Device Identifier
+ * @r_state: true if requested to be stopped
+ * @curr_state: true if currently stopped.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
+ bool *r_state, bool *curr_state)
+{
+ int ret;
+ u8 p_state, c_state;
+
+ if (!r_state && !curr_state)
+ return -EINVAL;
+
+ ret =
+ ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (r_state)
+ *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
+ if (curr_state)
+ *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
+
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
+ * @handle: Pointer to TISCI handle
+ * @id: Device Identifier
+ * @r_state: true if requested to be ON
+ * @curr_state: true if currently ON and active
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
+ bool *r_state, bool *curr_state)
+{
+ int ret;
+ u8 p_state, c_state;
+
+ if (!r_state && !curr_state)
+ return -EINVAL;
+
+ ret =
+ ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (r_state)
+ *r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
+ if (curr_state)
+ *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
+
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
+ * @handle: Pointer to TISCI handle
+ * @id: Device Identifier
+ * @curr_state: true if currently transitioning.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id,
+ bool *curr_state)
+{
+ int ret;
+ u8 state;
+
+ if (!curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
+ if (ret)
+ return ret;
+
+ *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
+
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_set_device_resets() - command to set resets for device managed
+ * by TISCI
+ * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * @id: Device Identifier
+ * @reset_state: Device specific reset bit field
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
+ u32 id, u32 reset_state)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_set_device_resets *req;
+ struct ti_sci_msg_hdr *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_set_device_resets *)xfer->xfer_buf;
+ req->id = id;
+ req->resets = reset_state;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+ ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_get_device_resets() - Get reset state for device managed
+ * by TISCI
+ * @handle: Pointer to TISCI handle
+ * @id: Device Identifier
+ * @reset_state: Pointer to reset state to populate
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
+ u32 id, u32 *reset_state)
+{
+ return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
+ NULL);
+}
+
+/**
+ * ti_sci_set_clock_state() - Set clock state helper
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @flags: Header flags as needed
+ * @state: State to request for the clock.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id,
+ u32 flags, u8 state)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_set_clock_state *req;
+ struct ti_sci_msg_hdr *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE,
+ flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+ req->request_state = state;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+ ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_get_clock_state() - Get clock state helper
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @programmed_state: State requested for clock to move to
+ * @current_state: State that the clock is currently in
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id,
+ u8 *programmed_state, u8 *current_state)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_get_clock_state *req;
+ struct ti_sci_msg_resp_get_clock_state *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ if (!programmed_state && !current_state)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->xfer_buf;
+
+ if (!ti_sci_is_response_ack(resp)) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ if (programmed_state)
+ *programmed_state = resp->programmed_state;
+ if (current_state)
+ *current_state = resp->current_state;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
+ * @can_change_freq: 'true' if frequency change is desired, else 'false'
+ * @enable_input_term: 'true' if input termination is desired, else 'false'
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
+ u8 clk_id, bool needs_ssc, bool can_change_freq,
+ bool enable_input_term)
+{
+ u32 flags = 0;
+
+ flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
+ flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
+ flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
+
+ return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
+ MSG_CLOCK_SW_STATE_REQ);
+}
+
+/**
+ * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ *
+ * NOTE: This clock must have been requested by get_clock previously.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id)
+{
+ return ti_sci_set_clock_state(handle, dev_id, clk_id, 0,
+ MSG_CLOCK_SW_STATE_UNREQ);
+}
+
+/**
+ * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ *
+ * NOTE: This clock must have been requested by get_clock previously.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id)
+{
+ return ti_sci_set_clock_state(handle, dev_id, clk_id, 0,
+ MSG_CLOCK_SW_STATE_AUTO);
+}
+
+/**
+ * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @req_state: state indicating if the clock is auto managed
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id, bool *req_state)
+{
+ u8 state = 0;
+ int ret;
+
+ if (!req_state)
+ return -EINVAL;
+
+ ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
+ if (ret)
+ return ret;
+
+ *req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_is_on() - Is the clock ON
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @req_state: state indicating if the clock is managed by us and enabled
+ * @curr_state: state indicating if the clock is ready for operation
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
+ u8 clk_id, bool *req_state, bool *curr_state)
+{
+ u8 c_state = 0, r_state = 0;
+ int ret;
+
+ if (!req_state && !curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
+ &r_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (req_state)
+ *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
+ if (curr_state)
+ *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_is_off() - Is the clock OFF
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @req_state: state indicating if the clock is managed by us and disabled
+ * @curr_state: state indicating if the clock is NOT ready for operation
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
+ u8 clk_id, bool *req_state, bool *curr_state)
+{
+ u8 c_state = 0, r_state = 0;
+ int ret;
+
+ if (!req_state && !curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
+ &r_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (req_state)
+ *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
+ if (curr_state)
+ *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @parent_id: Parent clock identifier to set
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id, u8 parent_id)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_set_clock_parent *req;
+ struct ti_sci_msg_hdr *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+ req->parent_id = parent_id;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+ ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_clk_get_parent() - Get current parent clock source
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @parent_id: Current clock parent
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id, u8 *parent_id)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_get_clock_parent *req;
+ struct ti_sci_msg_resp_get_clock_parent *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle || !parent_id)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf;
+
+ if (!ti_sci_is_response_ack(resp))
+ ret = -ENODEV;
+ else
+ *parent_id = resp->parent_id;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @num_parents: Returns he number of parents to the current clock.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id,
+ u8 *num_parents)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_get_clock_num_parents *req;
+ struct ti_sci_msg_resp_get_clock_num_parents *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle || !num_parents)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf;
+
+ if (!ti_sci_is_response_ack(resp))
+ ret = -ENODEV;
+ else
+ *num_parents = resp->num_parents;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @min_freq: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ * processed as close to this target frequency as possible.
+ * @max_freq: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @match_freq: Frequency match in Hz response.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id, u64 min_freq,
+ u64 target_freq, u64 max_freq,
+ u64 *match_freq)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_query_clock_freq *req;
+ struct ti_sci_msg_resp_query_clock_freq *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle || !match_freq)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+ req->min_freq_hz = min_freq;
+ req->target_freq_hz = target_freq;
+ req->max_freq_hz = max_freq;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->xfer_buf;
+
+ if (!ti_sci_is_response_ack(resp))
+ ret = -ENODEV;
+ else
+ *match_freq = resp->freq_hz;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @min_freq: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ * processed as close to this target frequency as possible.
+ * @max_freq: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id, u64 min_freq,
+ u64 target_freq, u64 max_freq)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_set_clock_freq *req;
+ struct ti_sci_msg_hdr *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+ req->min_freq_hz = min_freq;
+ req->target_freq_hz = target_freq;
+ req->max_freq_hz = max_freq;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+ ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/**
+ * ti_sci_cmd_clk_get_freq() - Get current frequency
+ * @handle: pointer to TI SCI handle
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @freq: Currently frequency in Hz
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
+ u32 dev_id, u8 clk_id, u64 *freq)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_get_clock_freq *req;
+ struct ti_sci_msg_resp_get_clock_freq *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle || !freq)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf;
+ req->dev_id = dev_id;
+ req->clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->xfer_buf;
+
+ if (!ti_sci_is_response_ack(resp))
+ ret = -ENODEV;
+ else
+ *freq = resp->freq_hz;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
+{
+ struct ti_sci_info *info;
+ struct ti_sci_msg_req_reboot *req;
+ struct ti_sci_msg_hdr *resp;
+ struct ti_sci_xfer *xfer;
+ struct device *dev;
+ int ret = 0;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ dev = info->dev;
+
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SYS_RESET,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ sizeof(*req), sizeof(*resp));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
+ return ret;
+ }
+ req = (struct ti_sci_msg_req_reboot *)xfer->xfer_buf;
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret) {
+ dev_err(dev, "Mbox send fail %d\n", ret);
+ goto fail;
+ }
+
+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+ if (!ti_sci_is_response_ack(resp))
+ ret = -ENODEV;
+ else
+ ret = 0;
+
+fail:
+ ti_sci_put_one_xfer(&info->minfo, xfer);
+
+ return ret;
+}
+
+/*
+ * ti_sci_setup_ops() - Setup the operations structures
+ * @info: pointer to TISCI pointer
+ */
+static void ti_sci_setup_ops(struct ti_sci_info *info)
+{
+ struct ti_sci_ops *ops = &info->handle.ops;
+ struct ti_sci_core_ops *core_ops = &ops->core_ops;
+ struct ti_sci_dev_ops *dops = &ops->dev_ops;
+ struct ti_sci_clk_ops *cops = &ops->clk_ops;
+
+ core_ops->reboot_device = ti_sci_cmd_core_reboot;
+
+ dops->get_device = ti_sci_cmd_get_device;
+ dops->idle_device = ti_sci_cmd_idle_device;
+ dops->put_device = ti_sci_cmd_put_device;
+
+ dops->is_valid = ti_sci_cmd_dev_is_valid;
+ dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
+ dops->is_idle = ti_sci_cmd_dev_is_idle;
+ dops->is_stop = ti_sci_cmd_dev_is_stop;
+ dops->is_on = ti_sci_cmd_dev_is_on;
+ dops->is_transitioning = ti_sci_cmd_dev_is_trans;
+ dops->set_device_resets = ti_sci_cmd_set_device_resets;
+ dops->get_device_resets = ti_sci_cmd_get_device_resets;
+
+ cops->get_clock = ti_sci_cmd_get_clock;
+ cops->idle_clock = ti_sci_cmd_idle_clock;
+ cops->put_clock = ti_sci_cmd_put_clock;
+ cops->is_auto = ti_sci_cmd_clk_is_auto;
+ cops->is_on = ti_sci_cmd_clk_is_on;
+ cops->is_off = ti_sci_cmd_clk_is_off;
+
+ cops->set_parent = ti_sci_cmd_clk_set_parent;
+ cops->get_parent = ti_sci_cmd_clk_get_parent;
+ cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
+
+ cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
+ cops->set_freq = ti_sci_cmd_clk_set_freq;
+ cops->get_freq = ti_sci_cmd_clk_get_freq;
+}
+
+/**
+ * ti_sci_get_handle() - Get the TI SCI handle for a device
+ * @dev: Pointer to device for which we want SCI handle
+ *
+ * NOTE: The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of TI SCI protocol library.
+ * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
+ * Return: pointer to handle if successful, else:
+ * -EPROBE_DEFER if the instance is not ready
+ * -ENODEV if the required node handler is missing
+ * -EINVAL if invalid conditions are encountered.
+ */
+const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
+{
+ struct device_node *ti_sci_np;
+ struct list_head *p;
+ struct ti_sci_handle *handle = NULL;
+ struct ti_sci_info *info;
+
+ if (!dev) {
+ pr_err("I need a device pointer\n");
+ return ERR_PTR(-EINVAL);
+ }
+ ti_sci_np = of_get_parent(dev->of_node);
+ if (!ti_sci_np) {
+ dev_err(dev, "No OF information\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ mutex_lock(&ti_sci_list_mutex);
+ list_for_each(p, &ti_sci_list) {
+ info = list_entry(p, struct ti_sci_info, node);
+ if (ti_sci_np == info->dev->of_node) {
+ handle = &info->handle;
+ info->users++;
+ break;
+ }
+ }
+ mutex_unlock(&ti_sci_list_mutex);
+ of_node_put(ti_sci_np);
+
+ if (!handle)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return handle;
+}
+EXPORT_SYMBOL_GPL(ti_sci_get_handle);
+
+/**
+ * ti_sci_put_handle() - Release the handle acquired by ti_sci_get_handle
+ * @handle: Handle acquired by ti_sci_get_handle
+ *
+ * NOTE: The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of TI SCI protocol library.
+ * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
+ *
+ * Return: 0 is successfully released
+ * if an error pointer was passed, it returns the error value back,
+ * if null was passed, it returns -EINVAL;
+ */
+int ti_sci_put_handle(const struct ti_sci_handle *handle)
+{
+ struct ti_sci_info *info;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+ mutex_lock(&ti_sci_list_mutex);
+ if (!WARN_ON(!info->users))
+ info->users--;
+ mutex_unlock(&ti_sci_list_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ti_sci_put_handle);
+
+static void devm_ti_sci_release(struct device *dev, void *res)
+{
+ const struct ti_sci_handle **ptr = res;
+ const struct ti_sci_handle *handle = *ptr;
+ int ret;
+
+ ret = ti_sci_put_handle(handle);
+ if (ret)
+ dev_err(dev, "failed to put handle %d\n", ret);
+}
+
+/**
+ * devm_ti_sci_get_handle() - Managed get handle
+ * @dev: device for which we want SCI handle for.
+ *
+ * NOTE: This releases the handle once the device resources are
+ * no longer needed. MUST NOT BE released with ti_sci_put_handle.
+ * The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of TI SCI protocol library.
+ *
+ * Return: 0 if all went fine, else corresponding error.
+ */
+const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
+{
+ const struct ti_sci_handle **ptr;
+ const struct ti_sci_handle *handle;
+
+ ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+ handle = ti_sci_get_handle(dev);
+
+ if (!IS_ERR(handle)) {
+ *ptr = handle;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return handle;
+}
+EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
+
+static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
+ void *cmd)
+{
+ struct ti_sci_info *info = reboot_to_ti_sci_info(nb);
+ const struct ti_sci_handle *handle = &info->handle;
+
+ ti_sci_cmd_core_reboot(handle);
+
+ /* call fail OR pass, we should not be here in the first place */
+ return NOTIFY_BAD;
+}
+
+/* Description for K2G */
+static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
+ .host_id = 2,
+ /* Conservative duration */
+ .max_rx_timeout_ms = 1000,
+ /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
+ .max_msgs = 20,
+ .max_msg_size = 64,
+};
+
+static const struct of_device_id ti_sci_of_match[] = {
+ {.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc},
+ { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_of_match);
+
+static int ti_sci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id;
+ const struct ti_sci_desc *desc;
+ struct ti_sci_xfer *xfer;
+ struct ti_sci_info *info = NULL;
+ struct ti_sci_xfers_info *minfo;
+ struct mbox_client *cl;
+ int ret = -EINVAL;
+ int i;
+ int reboot = 0;
+
+ of_id = of_match_device(ti_sci_of_match, dev);
+ if (!of_id) {
+ dev_err(dev, "OF data missing\n");
+ return -EINVAL;
+ }
+ desc = of_id->data;
+
+ info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = dev;
+ info->desc = desc;
+ reboot = of_property_read_bool(dev->of_node,
+ "ti,system-reboot-controller");
+ INIT_LIST_HEAD(&info->node);
+ minfo = &info->minfo;
+
+ /*
+ * Pre-allocate messages
+ * NEVER allocate more than what we can indicate in hdr.seq
+ * if we have data description bug, force a fix..
+ */
+ if (WARN_ON(desc->max_msgs >=
+ 1 << 8 * sizeof(((struct ti_sci_msg_hdr *)0)->seq)))
+ return -EINVAL;
+
+ minfo->xfer_block = devm_kcalloc(dev,
+ desc->max_msgs,
+ sizeof(*minfo->xfer_block),
+ GFP_KERNEL);
+ if (!minfo->xfer_block)
+ return -ENOMEM;
+
+ minfo->xfer_alloc_table = devm_kzalloc(dev,
+ BITS_TO_LONGS(desc->max_msgs)
+ * sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!minfo->xfer_alloc_table)
+ return -ENOMEM;
+ bitmap_zero(minfo->xfer_alloc_table, desc->max_msgs);
+
+ /* Pre-initialize the buffer pointer to pre-allocated buffers */
+ for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) {
+ xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size,
+ GFP_KERNEL);
+ if (!xfer->xfer_buf)
+ return -ENOMEM;
+
+ xfer->tx_message.buf = xfer->xfer_buf;
+ init_completion(&xfer->done);
+ }
+
+ ret = ti_sci_debugfs_create(pdev, info);
+ if (ret)
+ dev_warn(dev, "Failed to create debug file\n");
+
+ platform_set_drvdata(pdev, info);
+
+ cl = &info->cl;
+ cl->dev = dev;
+ cl->tx_block = false;
+ cl->rx_callback = ti_sci_rx_callback;
+ cl->knows_txdone = true;
+
+ spin_lock_init(&minfo->xfer_lock);
+ sema_init(&minfo->sem_xfer_count, desc->max_msgs);
+
+ info->chan_rx = mbox_request_channel_byname(cl, "rx");
+ if (IS_ERR(info->chan_rx)) {
+ ret = PTR_ERR(info->chan_rx);
+ goto out;
+ }
+
+ info->chan_tx = mbox_request_channel_byname(cl, "tx");
+ if (IS_ERR(info->chan_tx)) {
+ ret = PTR_ERR(info->chan_tx);
+ goto out;
+ }
+ ret = ti_sci_cmd_get_revision(info);
+ if (ret) {
+ dev_err(dev, "Unable to communicate with TISCI(%d)\n", ret);
+ goto out;
+ }
+
+ ti_sci_setup_ops(info);
+
+ if (reboot) {
+ info->nb.notifier_call = tisci_reboot_handler;
+ info->nb.priority = 128;
+
+ ret = register_restart_handler(&info->nb);
+ if (ret) {
+ dev_err(dev, "reboot registration fail(%d)\n", ret);
+ return ret;
+ }
+ }
+
+ dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
+ info->handle.version.abi_major, info->handle.version.abi_minor,
+ info->handle.version.firmware_revision,
+ info->handle.version.firmware_description);
+
+ mutex_lock(&ti_sci_list_mutex);
+ list_add_tail(&info->node, &ti_sci_list);
+ mutex_unlock(&ti_sci_list_mutex);
+
+ return of_platform_populate(dev->of_node, NULL, NULL, dev);
+out:
+ if (!IS_ERR(info->chan_tx))
+ mbox_free_channel(info->chan_tx);
+ if (!IS_ERR(info->chan_rx))
+ mbox_free_channel(info->chan_rx);
+ debugfs_remove(info->d);
+ return ret;
+}
+
+static int ti_sci_remove(struct platform_device *pdev)
+{
+ struct ti_sci_info *info;
+ struct device *dev = &pdev->dev;
+ int ret = 0;
+
+ of_platform_depopulate(dev);
+
+ info = platform_get_drvdata(pdev);
+
+ if (info->nb.notifier_call)
+ unregister_restart_handler(&info->nb);
+
+ mutex_lock(&ti_sci_list_mutex);
+ if (info->users)
+ ret = -EBUSY;
+ else
+ list_del(&info->node);
+ mutex_unlock(&ti_sci_list_mutex);
+
+ if (!ret) {
+ ti_sci_debugfs_destroy(pdev, info);
+
+ /* Safe to free channels since no more users */
+ mbox_free_channel(info->chan_tx);
+ mbox_free_channel(info->chan_rx);
+ }
+
+ return ret;
+}
+
+static struct platform_driver ti_sci_driver = {
+ .probe = ti_sci_probe,
+ .remove = ti_sci_remove,
+ .driver = {
+ .name = "ti-sci",
+ .of_match_table = of_match_ptr(ti_sci_of_match),
+ },
+};
+module_platform_driver(ti_sci_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI System Control Interface(SCI) driver");
+MODULE_AUTHOR("Nishanth Menon");
+MODULE_ALIAS("platform:ti-sci");
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
new file mode 100644
index 000000000000..9b611e9e6f6d
--- /dev/null
+++ b/drivers/firmware/ti_sci.h
@@ -0,0 +1,492 @@
+/*
+ * Texas Instruments System Control Interface (TISCI) Protocol
+ *
+ * Communication protocol with TI SCI hardware
+ * The system works in a message response protocol
+ * See: http://processors.wiki.ti.com/index.php/TISCI for details
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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 Texas Instruments Incorporated 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.
+ *
+ */
+
+#ifndef __TI_SCI_H
+#define __TI_SCI_H
+
+/* Generic Messages */
+#define TI_SCI_MSG_ENABLE_WDT 0x0000
+#define TI_SCI_MSG_WAKE_RESET 0x0001
+#define TI_SCI_MSG_VERSION 0x0002
+#define TI_SCI_MSG_WAKE_REASON 0x0003
+#define TI_SCI_MSG_GOODBYE 0x0004
+#define TI_SCI_MSG_SYS_RESET 0x0005
+
+/* Device requests */
+#define TI_SCI_MSG_SET_DEVICE_STATE 0x0200
+#define TI_SCI_MSG_GET_DEVICE_STATE 0x0201
+#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202
+
+/* Clock requests */
+#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100
+#define TI_SCI_MSG_GET_CLOCK_STATE 0x0101
+#define TI_SCI_MSG_SET_CLOCK_PARENT 0x0102
+#define TI_SCI_MSG_GET_CLOCK_PARENT 0x0103
+#define TI_SCI_MSG_GET_NUM_CLOCK_PARENTS 0x0104
+#define TI_SCI_MSG_SET_CLOCK_FREQ 0x010c
+#define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d
+#define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e
+
+/**
+ * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
+ * @type: Type of messages: One of TI_SCI_MSG* values
+ * @host: Host of the message
+ * @seq: Message identifier indicating a transfer sequence
+ * @flags: Flag for the message
+ */
+struct ti_sci_msg_hdr {
+ u16 type;
+ u8 host;
+ u8 seq;
+#define TI_SCI_MSG_FLAG(val) (1 << (val))
+#define TI_SCI_FLAG_REQ_GENERIC_NORESPONSE 0x0
+#define TI_SCI_FLAG_REQ_ACK_ON_RECEIVED TI_SCI_MSG_FLAG(0)
+#define TI_SCI_FLAG_REQ_ACK_ON_PROCESSED TI_SCI_MSG_FLAG(1)
+#define TI_SCI_FLAG_RESP_GENERIC_NACK 0x0
+#define TI_SCI_FLAG_RESP_GENERIC_ACK TI_SCI_MSG_FLAG(1)
+ /* Additional Flags */
+ u32 flags;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_version - Response for a message
+ * @hdr: Generic header
+ * @firmware_description: String describing the firmware
+ * @firmware_revision: Firmware revision
+ * @abi_major: Major version of the ABI that firmware supports
+ * @abi_minor: Minor version of the ABI that firmware supports
+ *
+ * In general, ABI version changes follow the rule that minor version increments
+ * are backward compatible. Major revision changes in ABI may not be
+ * backward compatible.
+ *
+ * Response to a generic message with message type TI_SCI_MSG_VERSION
+ */
+struct ti_sci_msg_resp_version {
+ struct ti_sci_msg_hdr hdr;
+ char firmware_description[32];
+ u16 firmware_revision;
+ u8 abi_major;
+ u8 abi_minor;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_reboot - Reboot the SoC
+ * @hdr: Generic Header
+ *
+ * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_reboot {
+ struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_device_state - Set the desired state of the device
+ * @hdr: Generic header
+ * @id: Indicates which device to modify
+ * @reserved: Reserved space in message, must be 0 for backward compatibility
+ * @state: The desired state of the device.
+ *
+ * Certain flags can also be set to alter the device state:
+ * + MSG_FLAG_DEVICE_WAKE_ENABLED - Configure the device to be a wake source.
+ * The meaning of this flag will vary slightly from device to device and from
+ * SoC to SoC but it generally allows the device to wake the SoC out of deep
+ * suspend states.
+ * + MSG_FLAG_DEVICE_RESET_ISO - Enable reset isolation for this device.
+ * + MSG_FLAG_DEVICE_EXCLUSIVE - Claim this device exclusively. When passed
+ * with STATE_RETENTION or STATE_ON, it will claim the device exclusively.
+ * If another host already has this device set to STATE_RETENTION or STATE_ON,
+ * the message will fail. Once successful, other hosts attempting to set
+ * STATE_RETENTION or STATE_ON will fail.
+ *
+ * Request type is TI_SCI_MSG_SET_DEVICE_STATE, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_set_device_state {
+ /* Additional hdr->flags options */
+#define MSG_FLAG_DEVICE_WAKE_ENABLED TI_SCI_MSG_FLAG(8)
+#define MSG_FLAG_DEVICE_RESET_ISO TI_SCI_MSG_FLAG(9)
+#define MSG_FLAG_DEVICE_EXCLUSIVE TI_SCI_MSG_FLAG(10)
+ struct ti_sci_msg_hdr hdr;
+ u32 id;
+ u32 reserved;
+
+#define MSG_DEVICE_SW_STATE_AUTO_OFF 0
+#define MSG_DEVICE_SW_STATE_RETENTION 1
+#define MSG_DEVICE_SW_STATE_ON 2
+ u8 state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_device_state - Request to get device.
+ * @hdr: Generic header
+ * @id: Device Identifier
+ *
+ * Request type is TI_SCI_MSG_GET_DEVICE_STATE, responded device state
+ * information
+ */
+struct ti_sci_msg_req_get_device_state {
+ struct ti_sci_msg_hdr hdr;
+ u32 id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_device_state - Response to get device request.
+ * @hdr: Generic header
+ * @context_loss_count: Indicates how many times the device has lost context. A
+ * driver can use this monotonic counter to determine if the device has
+ * lost context since the last time this message was exchanged.
+ * @resets: Programmed state of the reset lines.
+ * @programmed_state: The state as programmed by set_device.
+ * - Uses the MSG_DEVICE_SW_* macros
+ * @current_state: The actual state of the hardware.
+ *
+ * Response to request TI_SCI_MSG_GET_DEVICE_STATE.
+ */
+struct ti_sci_msg_resp_get_device_state {
+ struct ti_sci_msg_hdr hdr;
+ u32 context_loss_count;
+ u32 resets;
+ u8 programmed_state;
+#define MSG_DEVICE_HW_STATE_OFF 0
+#define MSG_DEVICE_HW_STATE_ON 1
+#define MSG_DEVICE_HW_STATE_TRANS 2
+ u8 current_state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_device_resets - Set the desired resets
+ * configuration of the device
+ * @hdr: Generic header
+ * @id: Indicates which device to modify
+ * @resets: A bit field of resets for the device. The meaning, behavior,
+ * and usage of the reset flags are device specific. 0 for a bit
+ * indicates releasing the reset represented by that bit while 1
+ * indicates keeping it held.
+ *
+ * Request type is TI_SCI_MSG_SET_DEVICE_RESETS, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_set_device_resets {
+ struct ti_sci_msg_hdr hdr;
+ u32 id;
+ u32 resets;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_clock_state - Request to setup a Clock state
+ * @hdr: Generic Header, Certain flags can be set specific to the clocks:
+ * MSG_FLAG_CLOCK_ALLOW_SSC: Allow this clock to be modified
+ * via spread spectrum clocking.
+ * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE: Allow this clock's
+ * frequency to be changed while it is running so long as it
+ * is within the min/max limits.
+ * MSG_FLAG_CLOCK_INPUT_TERM: Enable input termination, this
+ * is only applicable to clock inputs on the SoC pseudo-device.
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @request_state: Request the state for the clock to be set to.
+ * MSG_CLOCK_SW_STATE_UNREQ: The IP does not require this clock,
+ * it can be disabled, regardless of the state of the device
+ * MSG_CLOCK_SW_STATE_AUTO: Allow the System Controller to
+ * automatically manage the state of this clock. If the device
+ * is enabled, then the clock is enabled. If the device is set
+ * to off or retention, then the clock is internally set as not
+ * being required by the device.(default)
+ * MSG_CLOCK_SW_STATE_REQ: Configure the clock to be enabled,
+ * regardless of the state of the device.
+ *
+ * Normally, all required clocks are managed by TISCI entity, this is used
+ * only for specific control *IF* required. Auto managed state is
+ * MSG_CLOCK_SW_STATE_AUTO, in other states, TISCI entity assume remote
+ * will explicitly control.
+ *
+ * Request type is TI_SCI_MSG_SET_CLOCK_STATE, response is a generic
+ * ACK or NACK message.
+ */
+struct ti_sci_msg_req_set_clock_state {
+ /* Additional hdr->flags options */
+#define MSG_FLAG_CLOCK_ALLOW_SSC TI_SCI_MSG_FLAG(8)
+#define MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE TI_SCI_MSG_FLAG(9)
+#define MSG_FLAG_CLOCK_INPUT_TERM TI_SCI_MSG_FLAG(10)
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u8 clk_id;
+#define MSG_CLOCK_SW_STATE_UNREQ 0
+#define MSG_CLOCK_SW_STATE_AUTO 1
+#define MSG_CLOCK_SW_STATE_REQ 2
+ u8 request_state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_state - Request for clock state
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to get state of.
+ *
+ * Request type is TI_SCI_MSG_GET_CLOCK_STATE, response is state
+ * of the clock
+ */
+struct ti_sci_msg_req_get_clock_state {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u8 clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_state - Response to get clock state
+ * @hdr: Generic Header
+ * @programmed_state: Any programmed state of the clock. This is one of
+ * MSG_CLOCK_SW_STATE* values.
+ * @current_state: Current state of the clock. This is one of:
+ * MSG_CLOCK_HW_STATE_NOT_READY: Clock is not ready
+ * MSG_CLOCK_HW_STATE_READY: Clock is ready
+ *
+ * Response to TI_SCI_MSG_GET_CLOCK_STATE.
+ */
+struct ti_sci_msg_resp_get_clock_state {
+ struct ti_sci_msg_hdr hdr;
+ u8 programmed_state;
+#define MSG_CLOCK_HW_STATE_NOT_READY 0
+#define MSG_CLOCK_HW_STATE_READY 1
+ u8 current_state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_clock_parent - Set the clock parent
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @parent_id: The new clock parent is selectable by an index via this
+ * parameter.
+ *
+ * Request type is TI_SCI_MSG_SET_CLOCK_PARENT, response is generic
+ * ACK / NACK message.
+ */
+struct ti_sci_msg_req_set_clock_parent {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u8 clk_id;
+ u8 parent_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_parent - Get the clock parent
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to get the parent for.
+ *
+ * Request type is TI_SCI_MSG_GET_CLOCK_PARENT, response is parent information
+ */
+struct ti_sci_msg_req_get_clock_parent {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u8 clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_parent - Response with clock parent
+ * @hdr: Generic Header
+ * @parent_id: The current clock parent
+ *
+ * Response to TI_SCI_MSG_GET_CLOCK_PARENT.
+ */
+struct ti_sci_msg_resp_get_clock_parent {
+ struct ti_sci_msg_hdr hdr;
+ u8 parent_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_num_parents - Request to get clock parents
+ * @hdr: Generic header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * This request provides information about how many clock parent options
+ * are available for a given clock to a device. This is typically used
+ * for input clocks.
+ *
+ * Request type is TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_get_clock_num_parents {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u8 clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_num_parents - Response for get clk parents
+ * @hdr: Generic header
+ * @num_parents: Number of clock parents
+ *
+ * Response to TI_SCI_MSG_GET_NUM_CLOCK_PARENTS
+ */
+struct ti_sci_msg_resp_get_clock_num_parents {
+ struct ti_sci_msg_hdr hdr;
+ u8 num_parents;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_query_clock_freq - Request to query a frequency
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq_hz: The target clock frequency. A frequency will be found
+ * as close to this target frequency as possible.
+ * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * NOTE: Normally clock frequency management is automatically done by TISCI
+ * entity. In case of specific requests, TISCI evaluates capability to achieve
+ * requested frequency within provided range and responds with
+ * result message.
+ *
+ * Request type is TI_SCI_MSG_QUERY_CLOCK_FREQ, response is appropriate message,
+ * or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_query_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u64 min_freq_hz;
+ u64 target_freq_hz;
+ u64 max_freq_hz;
+ u8 clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_query_clock_freq - Response to a clock frequency query
+ * @hdr: Generic Header
+ * @freq_hz: Frequency that is the best match in Hz.
+ *
+ * Response to request type TI_SCI_MSG_QUERY_CLOCK_FREQ. NOTE: if the request
+ * cannot be satisfied, the message will be of type NACK.
+ */
+struct ti_sci_msg_resp_query_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ u64 freq_hz;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_clock_freq - Request to setup a clock frequency
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq_hz: The target clock frequency. The clock will be programmed
+ * at a rate as close to this target frequency as possible.
+ * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * NOTE: Normally clock frequency management is automatically done by TISCI
+ * entity. In case of specific requests, TISCI evaluates capability to achieve
+ * requested range and responds with success/failure message.
+ *
+ * This sets the desired frequency for a clock within an allowable
+ * range. This message will fail on an enabled clock unless
+ * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE is set for the clock. Additionally,
+ * if other clocks have their frequency modified due to this message,
+ * they also must have the MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE or be disabled.
+ *
+ * Calling set frequency on a clock input to the SoC pseudo-device will
+ * inform the PMMC of that clock's frequency. Setting a frequency of
+ * zero will indicate the clock is disabled.
+ *
+ * Calling set frequency on clock outputs from the SoC pseudo-device will
+ * function similarly to setting the clock frequency on a device.
+ *
+ * Request type is TI_SCI_MSG_SET_CLOCK_FREQ, response is a generic ACK/NACK
+ * message.
+ */
+struct ti_sci_msg_req_set_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u64 min_freq_hz;
+ u64 target_freq_hz;
+ u64 max_freq_hz;
+ u8 clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_freq - Request to get the clock frequency
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * NOTE: Normally clock frequency management is automatically done by TISCI
+ * entity. In some cases, clock frequencies are configured by host.
+ *
+ * Request type is TI_SCI_MSG_GET_CLOCK_FREQ, responded with clock frequency
+ * that the clock is currently at.
+ */
+struct ti_sci_msg_req_get_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ u32 dev_id;
+ u8 clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_freq - Response of clock frequency request
+ * @hdr: Generic Header
+ * @freq_hz: Frequency that the clock is currently on, in Hz.
+ *
+ * Response to request type TI_SCI_MSG_GET_CLOCK_FREQ.
+ */
+struct ti_sci_msg_resp_get_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ u64 freq_hz;
+} __packed;
+
+#endif /* __TI_SCI_H */
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 944c17b48d23..e4c55c5f9988 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -406,7 +406,7 @@ static long stm_generic_set_options(struct stm_data *stm_data,
return 0;
}
-static ssize_t stm_generic_packet(struct stm_data *stm_data,
+static ssize_t notrace stm_generic_packet(struct stm_data *stm_data,
unsigned int master,
unsigned int channel,
unsigned int packet,
diff --git a/drivers/hwtracing/intel_th/sth.c b/drivers/hwtracing/intel_th/sth.c
index e1aee61dd7b3..b03444624648 100644
--- a/drivers/hwtracing/intel_th/sth.c
+++ b/drivers/hwtracing/intel_th/sth.c
@@ -67,10 +67,13 @@ static void sth_iowrite(void __iomem *dest, const unsigned char *payload,
}
}
-static ssize_t sth_stm_packet(struct stm_data *stm_data, unsigned int master,
- unsigned int channel, unsigned int packet,
- unsigned int flags, unsigned int size,
- const unsigned char *payload)
+static ssize_t notrace sth_stm_packet(struct stm_data *stm_data,
+ unsigned int master,
+ unsigned int channel,
+ unsigned int packet,
+ unsigned int flags,
+ unsigned int size,
+ const unsigned char *payload)
{
struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
struct intel_th_channel __iomem *out =
diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig
index 847a39b35307..723e2d90083d 100644
--- a/drivers/hwtracing/stm/Kconfig
+++ b/drivers/hwtracing/stm/Kconfig
@@ -39,4 +39,15 @@ config STM_SOURCE_HEARTBEAT
If you want to send heartbeat messages over STM devices,
say Y.
+config STM_SOURCE_FTRACE
+ tristate "Copy the output from kernel Ftrace to STM engine"
+ depends on FUNCTION_TRACER
+ help
+ This option can be used to copy the output from kernel Ftrace
+ to STM engine. Enabling this option will introduce a slight
+ timing effect.
+
+ If you want to send kernel Ftrace messages over STM devices,
+ say Y.
+
endif
diff --git a/drivers/hwtracing/stm/Makefile b/drivers/hwtracing/stm/Makefile
index a9ce3d487e57..3abd84ce13d4 100644
--- a/drivers/hwtracing/stm/Makefile
+++ b/drivers/hwtracing/stm/Makefile
@@ -6,6 +6,8 @@ obj-$(CONFIG_STM_DUMMY) += dummy_stm.o
obj-$(CONFIG_STM_SOURCE_CONSOLE) += stm_console.o
obj-$(CONFIG_STM_SOURCE_HEARTBEAT) += stm_heartbeat.o
+obj-$(CONFIG_STM_SOURCE_FTRACE) += stm_ftrace.o
stm_console-y := console.o
stm_heartbeat-y := heartbeat.o
+stm_ftrace-y := ftrace.o
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index a6ea387b5b00..0e731143f6a4 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -427,7 +427,7 @@ static int stm_file_assign(struct stm_file *stmf, char *id, unsigned int width)
return ret;
}
-static ssize_t stm_write(struct stm_data *data, unsigned int master,
+static ssize_t notrace stm_write(struct stm_data *data, unsigned int master,
unsigned int channel, const char *buf, size_t count)
{
unsigned int flags = STP_PACKET_TIMESTAMPED;
@@ -1123,8 +1123,9 @@ void stm_source_unregister_device(struct stm_source_data *data)
}
EXPORT_SYMBOL_GPL(stm_source_unregister_device);
-int stm_source_write(struct stm_source_data *data, unsigned int chan,
- const char *buf, size_t count)
+int notrace stm_source_write(struct stm_source_data *data,
+ unsigned int chan,
+ const char *buf, size_t count)
{
struct stm_source_device *src = data->src;
struct stm_device *stm;
diff --git a/drivers/hwtracing/stm/dummy_stm.c b/drivers/hwtracing/stm/dummy_stm.c
index a86612d989f9..c5f94ca31c4d 100644
--- a/drivers/hwtracing/stm/dummy_stm.c
+++ b/drivers/hwtracing/stm/dummy_stm.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <linux/stm.h>
-static ssize_t
+static ssize_t notrace
dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
unsigned int channel, unsigned int packet, unsigned int flags,
unsigned int size, const unsigned char *payload)
diff --git a/drivers/hwtracing/stm/ftrace.c b/drivers/hwtracing/stm/ftrace.c
new file mode 100644
index 000000000000..bd126a7c6da2
--- /dev/null
+++ b/drivers/hwtracing/stm/ftrace.c
@@ -0,0 +1,87 @@
+/*
+ * Simple kernel driver to link kernel Ftrace and an STM device
+ * Copyright (c) 2016, Linaro Ltd.
+ *
+ * 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.
+ *
+ * STM Ftrace will be registered as a trace_export.
+ */
+
+#include <linux/module.h>
+#include <linux/stm.h>
+#include <linux/trace.h>
+
+#define STM_FTRACE_NR_CHANNELS 1
+#define STM_FTRACE_CHAN 0
+
+static int stm_ftrace_link(struct stm_source_data *data);
+static void stm_ftrace_unlink(struct stm_source_data *data);
+
+static struct stm_ftrace {
+ struct stm_source_data data;
+ struct trace_export ftrace;
+} stm_ftrace = {
+ .data = {
+ .name = "ftrace",
+ .nr_chans = STM_FTRACE_NR_CHANNELS,
+ .link = stm_ftrace_link,
+ .unlink = stm_ftrace_unlink,
+ },
+};
+
+/**
+ * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
+ * @buf: buffer containing the data packet
+ * @len: length of the data packet
+ */
+static void notrace
+stm_ftrace_write(const void *buf, unsigned int len)
+{
+ stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len);
+}
+
+static int stm_ftrace_link(struct stm_source_data *data)
+{
+ struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
+
+ sf->ftrace.write = stm_ftrace_write;
+
+ return register_ftrace_export(&sf->ftrace);
+}
+
+static void stm_ftrace_unlink(struct stm_source_data *data)
+{
+ struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
+
+ unregister_ftrace_export(&sf->ftrace);
+}
+
+static int __init stm_ftrace_init(void)
+{
+ int ret;
+
+ ret = stm_source_register_device(NULL, &stm_ftrace.data);
+ if (ret)
+ pr_err("Failed to register stm_source - ftrace.\n");
+
+ return ret;
+}
+
+static void __exit stm_ftrace_exit(void)
+{
+ stm_source_unregister_device(&stm_ftrace.data);
+}
+
+module_init(stm_ftrace_init);
+module_exit(stm_ftrace_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("stm_ftrace driver");
+MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 11edabf425ae..efc3354d60ae 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -7,6 +7,7 @@ menu "I2C support"
config I2C
tristate "I2C support"
select RT_MUTEXES
+ select IRQ_DOMAIN
---help---
I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
many micro controller applications and developed by Philips. SMBus,
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d252276feadf..0cdc8443deab 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -426,7 +426,7 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
config I2C_CADENCE
tristate "Cadence I2C Controller"
- depends on ARCH_ZYNQ || ARM64
+ depends on ARCH_ZYNQ || ARM64 || XTENSA
help
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.
@@ -597,6 +597,16 @@ config I2C_IMX
This driver can also be built as a module. If so, the module
will be called i2c-imx.
+config I2C_IMX_LPI2C
+ tristate "IMX Low Power I2C interface"
+ depends on ARCH_MXC || COMPILE_TEST
+ help
+ Say Y here if you want to use the Low Power IIC bus controller
+ on the Freescale i.MX processors.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-imx-lpi2c.
+
config I2C_IOP3XX
tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
@@ -763,7 +773,7 @@ config I2C_PUV3
config I2C_PXA
tristate "Intel PXA2XX I2C adapter"
- depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF)
+ depends on ARCH_PXA || ARCH_MMP || ARCH_MVEBU || (X86_32 && PCI && OF)
help
If you have devices in the PXA I2C bus, say yes to this option.
This driver can also be built as a module. If so, the module
@@ -1150,6 +1160,17 @@ config I2C_ELEKTOR
This support is also available as a module. If so, the module
will be called i2c-elektor.
+config I2C_MLXCPLD
+ tristate "Mellanox I2C driver"
+ depends on X86_64
+ help
+ This exposes the Mellanox platform I2C busses to the linux I2C layer
+ for X86 based systems.
+ Controller is implemented as CPLD logic.
+
+ This driver can also be built as a module. If so, the module will be
+ called as i2c-mlxcpld.
+
config I2C_PCA_ISA
tristate "PCA9564/PCA9665 on an ISA bus"
depends on ISA
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 29764cc20a44..1c1bac87a9db 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o
obj-$(CONFIG_I2C_IMX) += i2c-imx.o
+obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-lpi2c.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
@@ -116,6 +117,7 @@ obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o
obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o
obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
+obj-$(CONFIG_I2C_MLXCPLD) += i2c-mlxcpld.o
obj-$(CONFIG_I2C_OPAL) += i2c-opal.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index 4351a9343058..13f07482ec68 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -489,7 +489,7 @@ static const struct i2c_algorithm axxia_i2c_algo = {
.functionality = axxia_i2c_func,
};
-static struct i2c_adapter_quirks axxia_i2c_quirks = {
+static const struct i2c_adapter_quirks axxia_i2c_quirks = {
.max_read_len = 255,
.max_write_len = 255,
};
diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
index 326b3db02c48..318df559adc5 100644
--- a/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -395,7 +395,7 @@ static const struct i2c_algorithm bcm_iproc_algo = {
.functionality = bcm_iproc_i2c_functionality,
};
-static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
+static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
/* need to reserve one byte in the FIFO for the slave address */
.max_read_len = M_TX_RX_FIFO_SIZE - 1,
};
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index d4f3239b5686..c3436f627028 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -50,20 +50,19 @@
#define BCM2835_I2C_S_CLKT BIT(9)
#define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */
-#define BCM2835_I2C_BITMSK_S 0x03FF
-
#define BCM2835_I2C_CDIV_MIN 0x0002
#define BCM2835_I2C_CDIV_MAX 0xFFFE
-#define BCM2835_I2C_TIMEOUT (msecs_to_jiffies(1000))
-
struct bcm2835_i2c_dev {
struct device *dev;
void __iomem *regs;
struct clk *clk;
int irq;
+ u32 bus_clk_rate;
struct i2c_adapter adapter;
struct completion completion;
+ struct i2c_msg *curr_msg;
+ int num_msgs;
u32 msg_err;
u8 *msg_buf;
size_t msg_buf_remaining;
@@ -80,6 +79,30 @@ static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg)
return readl(i2c_dev->regs + reg);
}
+static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
+{
+ u32 divider;
+
+ divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk),
+ i2c_dev->bus_clk_rate);
+ /*
+ * Per the datasheet, the register is always interpreted as an even
+ * number, by rounding down. In other words, the LSB is ignored. So,
+ * if the LSB is set, increment the divider to avoid any issue.
+ */
+ if (divider & 1)
+ divider++;
+ if ((divider < BCM2835_I2C_CDIV_MIN) ||
+ (divider > BCM2835_I2C_CDIV_MAX)) {
+ dev_err_ratelimited(i2c_dev->dev, "Invalid clock-frequency\n");
+ return -EINVAL;
+ }
+
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
+
+ return 0;
+}
+
static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev)
{
u32 val;
@@ -110,106 +133,159 @@ static void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev)
}
}
+/*
+ * Repeated Start Condition (Sr)
+ * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it
+ * talks about reading from a slave with 10 bit address. This is achieved by
+ * issuing a write, poll the I2CS.TA flag and wait for it to be set, and then
+ * issue a read.
+ * A comment in https://github.com/raspberrypi/linux/issues/254 shows how the
+ * firmware actually does it using polling and says that it's a workaround for
+ * a problem in the state machine.
+ * It turns out that it is possible to use the TXW interrupt to know when the
+ * transfer is active, provided the FIFO has not been prefilled.
+ */
+
+static void bcm2835_i2c_start_transfer(struct bcm2835_i2c_dev *i2c_dev)
+{
+ u32 c = BCM2835_I2C_C_ST | BCM2835_I2C_C_I2CEN;
+ struct i2c_msg *msg = i2c_dev->curr_msg;
+ bool last_msg = (i2c_dev->num_msgs == 1);
+
+ if (!i2c_dev->num_msgs)
+ return;
+
+ i2c_dev->num_msgs--;
+ i2c_dev->msg_buf = msg->buf;
+ i2c_dev->msg_buf_remaining = msg->len;
+
+ if (msg->flags & I2C_M_RD)
+ c |= BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR;
+ else
+ c |= BCM2835_I2C_C_INTT;
+
+ if (last_msg)
+ c |= BCM2835_I2C_C_INTD;
+
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr);
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len);
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c);
+}
+
+/*
+ * Note about I2C_C_CLEAR on error:
+ * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in
+ * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through
+ * the state machine to send a NACK and a STOP. Since we're setting CLEAR
+ * without I2CEN, that NACK will be hanging around queued up for next time
+ * we start the engine.
+ */
+
static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data)
{
struct bcm2835_i2c_dev *i2c_dev = data;
u32 val, err;
val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S);
- val &= BCM2835_I2C_BITMSK_S;
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, val);
err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR);
if (err) {
i2c_dev->msg_err = err;
- complete(&i2c_dev->completion);
- return IRQ_HANDLED;
- }
-
- if (val & BCM2835_I2C_S_RXD) {
- bcm2835_drain_rxfifo(i2c_dev);
- if (!(val & BCM2835_I2C_S_DONE))
- return IRQ_HANDLED;
+ goto complete;
}
if (val & BCM2835_I2C_S_DONE) {
- if (i2c_dev->msg_buf_remaining)
+ if (i2c_dev->curr_msg->flags & I2C_M_RD) {
+ bcm2835_drain_rxfifo(i2c_dev);
+ val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S);
+ }
+
+ if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining)
i2c_dev->msg_err = BCM2835_I2C_S_LEN;
else
i2c_dev->msg_err = 0;
- complete(&i2c_dev->completion);
- return IRQ_HANDLED;
+ goto complete;
}
- if (val & BCM2835_I2C_S_TXD) {
+ if (val & BCM2835_I2C_S_TXW) {
+ if (!i2c_dev->msg_buf_remaining) {
+ i2c_dev->msg_err = val | BCM2835_I2C_S_LEN;
+ goto complete;
+ }
+
bcm2835_fill_txfifo(i2c_dev);
+
+ if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) {
+ i2c_dev->curr_msg++;
+ bcm2835_i2c_start_transfer(i2c_dev);
+ }
+
+ return IRQ_HANDLED;
+ }
+
+ if (val & BCM2835_I2C_S_RXR) {
+ if (!i2c_dev->msg_buf_remaining) {
+ i2c_dev->msg_err = val | BCM2835_I2C_S_LEN;
+ goto complete;
+ }
+
+ bcm2835_drain_rxfifo(i2c_dev);
return IRQ_HANDLED;
}
return IRQ_NONE;
+
+complete:
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR);
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, BCM2835_I2C_S_CLKT |
+ BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE);
+ complete(&i2c_dev->completion);
+
+ return IRQ_HANDLED;
}
-static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev,
- struct i2c_msg *msg)
+static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
+ int num)
{
- u32 c;
+ struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
unsigned long time_left;
+ int i, ret;
- i2c_dev->msg_buf = msg->buf;
- i2c_dev->msg_buf_remaining = msg->len;
- reinit_completion(&i2c_dev->completion);
+ for (i = 0; i < (num - 1); i++)
+ if (msgs[i].flags & I2C_M_RD) {
+ dev_warn_once(i2c_dev->dev,
+ "only one read message supported, has to be last\n");
+ return -EOPNOTSUPP;
+ }
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR);
+ ret = bcm2835_i2c_set_divider(i2c_dev);
+ if (ret)
+ return ret;
- if (msg->flags & I2C_M_RD) {
- c = BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR;
- } else {
- c = BCM2835_I2C_C_INTT;
- bcm2835_fill_txfifo(i2c_dev);
- }
- c |= BCM2835_I2C_C_ST | BCM2835_I2C_C_INTD | BCM2835_I2C_C_I2CEN;
+ i2c_dev->curr_msg = msgs;
+ i2c_dev->num_msgs = num;
+ reinit_completion(&i2c_dev->completion);
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr);
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len);
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c);
+ bcm2835_i2c_start_transfer(i2c_dev);
time_left = wait_for_completion_timeout(&i2c_dev->completion,
- BCM2835_I2C_TIMEOUT);
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR);
+ adap->timeout);
if (!time_left) {
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C,
+ BCM2835_I2C_C_CLEAR);
dev_err(i2c_dev->dev, "i2c transfer timed out\n");
return -ETIMEDOUT;
}
- if (likely(!i2c_dev->msg_err))
- return 0;
+ if (!i2c_dev->msg_err)
+ return num;
- if ((i2c_dev->msg_err & BCM2835_I2C_S_ERR) &&
- (msg->flags & I2C_M_IGNORE_NAK))
- return 0;
-
- dev_err(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err);
+ dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err);
if (i2c_dev->msg_err & BCM2835_I2C_S_ERR)
return -EREMOTEIO;
- else
- return -EIO;
-}
-
-static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
- int num)
-{
- struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
- int i;
- int ret = 0;
-
- for (i = 0; i < num; i++) {
- ret = bcm2835_i2c_xfer_msg(i2c_dev, &msgs[i]);
- if (ret)
- break;
- }
- return ret ?: i;
+ return -EIO;
}
static u32 bcm2835_i2c_func(struct i2c_adapter *adap)
@@ -235,7 +311,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
{
struct bcm2835_i2c_dev *i2c_dev;
struct resource *mem, *irq;
- u32 bus_clk_rate, divider;
int ret;
struct i2c_adapter *adap;
@@ -259,27 +334,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
}
ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
- &bus_clk_rate);
+ &i2c_dev->bus_clk_rate);
if (ret < 0) {
dev_warn(&pdev->dev,
"Could not read clock-frequency property\n");
- bus_clk_rate = 100000;
- }
-
- divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), bus_clk_rate);
- /*
- * Per the datasheet, the register is always interpreted as an even
- * number, by rounding down. In other words, the LSB is ignored. So,
- * if the LSB is set, increment the divider to avoid any issue.
- */
- if (divider & 1)
- divider++;
- if ((divider < BCM2835_I2C_CDIV_MIN) ||
- (divider > BCM2835_I2C_CDIV_MAX)) {
- dev_err(&pdev->dev, "Invalid clock-frequency\n");
- return -ENODEV;
+ i2c_dev->bus_clk_rate = 100000;
}
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index b403fa5ecf49..6d81c56184d3 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -536,6 +536,8 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
intr_mask = DW_IC_INTR_DEFAULT_MASK;
for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
+ u32 flags = msgs[dev->msg_write_idx].flags;
+
/*
* if target address has changed, we need to
* reprogram the target address in the i2c
@@ -581,8 +583,15 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
* detected from the registers so we set it always
* when writing/reading the last byte.
*/
+
+ /*
+ * i2c-core.c always sets the buffer length of
+ * I2C_FUNC_SMBUS_BLOCK_DATA to 1. The length will
+ * be adjusted when receiving the first byte.
+ * Thus we can't stop the transaction here.
+ */
if (dev->msg_write_idx == dev->msgs_num - 1 &&
- buf_len == 1)
+ buf_len == 1 && !(flags & I2C_M_RECV_LEN))
cmd |= BIT(9);
if (need_restart) {
@@ -607,7 +616,12 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
dev->tx_buf = buf;
dev->tx_buf_len = buf_len;
- if (buf_len > 0) {
+ /*
+ * Because we don't know the buffer length in the
+ * I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop
+ * the transaction here.
+ */
+ if (buf_len > 0 || flags & I2C_M_RECV_LEN) {
/* more bytes to be written */
dev->status |= STATUS_WRITE_IN_PROGRESS;
break;
@@ -628,6 +642,24 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
dw_writel(dev, intr_mask, DW_IC_INTR_MASK);
}
+static u8
+i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len)
+{
+ struct i2c_msg *msgs = dev->msgs;
+ u32 flags = msgs[dev->msg_read_idx].flags;
+
+ /*
+ * Adjust the buffer length and mask the flag
+ * after receiving the first byte.
+ */
+ len += (flags & I2C_CLIENT_PEC) ? 2 : 1;
+ dev->tx_buf_len = len - min_t(u8, len, dev->rx_outstanding);
+ msgs[dev->msg_read_idx].len = len;
+ msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN;
+
+ return len;
+}
+
static void
i2c_dw_read(struct dw_i2c_dev *dev)
{
@@ -652,7 +684,15 @@ i2c_dw_read(struct dw_i2c_dev *dev)
rx_valid = dw_readl(dev, DW_IC_RXFLR);
for (; len > 0 && rx_valid > 0; len--, rx_valid--) {
- *buf++ = dw_readl(dev, DW_IC_DATA_CMD);
+ u32 flags = msgs[dev->msg_read_idx].flags;
+
+ *buf = dw_readl(dev, DW_IC_DATA_CMD);
+ /* Ensure length byte is a valid value */
+ if (flags & I2C_M_RECV_LEN &&
+ *buf <= I2C_SMBUS_BLOCK_MAX && *buf > 0) {
+ len = i2c_dw_recv_len(dev, *buf);
+ }
+ buf++;
dev->rx_outstanding--;
}
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 0d44d2ae7d4c..26250b425e2f 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -22,6 +22,14 @@
*
*/
+#include <linux/i2c.h>
+
+#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
+ I2C_FUNC_SMBUS_BYTE | \
+ I2C_FUNC_SMBUS_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WORD_DATA | \
+ I2C_FUNC_SMBUS_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_I2C_BLOCK)
#define DW_IC_CON_MASTER 0x1
#define DW_IC_CON_SPEED_STD 0x2
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 96f8230cd2d3..d6423cfac588 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -71,12 +71,6 @@ struct dw_pci_controller {
DW_IC_CON_SLAVE_DISABLE | \
DW_IC_CON_RESTART_EN)
-#define DW_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
- I2C_FUNC_SMBUS_BYTE | \
- I2C_FUNC_SMBUS_BYTE_DATA | \
- I2C_FUNC_SMBUS_WORD_DATA | \
- I2C_FUNC_SMBUS_I2C_BLOCK)
-
/* Merrifield HCNT/LCNT/SDA hold time */
static struct dw_scl_sda_cfg mrfld_config = {
.ss_hcnt = 0x2f8,
@@ -147,6 +141,7 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
.tx_fifo_depth = 32,
.rx_fifo_depth = 32,
+ .functionality = I2C_FUNC_10BIT_ADDR,
.clk_khz = 25000,
.setup = mfld_setup,
},
@@ -155,6 +150,7 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
.tx_fifo_depth = 64,
.rx_fifo_depth = 64,
+ .functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &mrfld_config,
.setup = mrfld_setup,
},
@@ -249,7 +245,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
}
dev->functionality = controller->functionality |
- DW_DEFAULT_FUNCTIONALITY;
+ DW_IC_DEFAULT_FUNCTIONALITY;
dev->master_cfg = controller->bus_cfg;
if (controller->scl_sda_cfg) {
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 0b42a12171f3..08153ea4d848 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -176,9 +176,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
dev->irq = irq;
platform_set_drvdata(pdev, dev);
- /* fast mode by default because of legacy reasons */
- dev->clk_freq = 400000;
-
if (pdata) {
dev->clk_freq = pdata->i2c_scl_freq;
} else {
@@ -193,8 +190,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
}
acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
- if (acpi_speed)
- dev->clk_freq = acpi_speed;
+ /*
+ * Find bus speed from the "clock-frequency" device property, ACPI
+ * or by using fast mode if neither is set.
+ */
+ if (acpi_speed && dev->clk_freq)
+ dev->clk_freq = min(dev->clk_freq, acpi_speed);
+ else if (acpi_speed || dev->clk_freq)
+ dev->clk_freq = max(dev->clk_freq, acpi_speed);
+ else
+ dev->clk_freq = 400000;
if (has_acpi_companion(&pdev->dev))
dw_i2c_acpi_configure(pdev);
@@ -214,13 +219,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
if (r)
return r;
- dev->functionality =
- I2C_FUNC_I2C |
- I2C_FUNC_10BIT_ADDR |
- I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK;
+ dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
DW_IC_CON_RESTART_EN;
diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
index 8acda2aa1558..69075a32073e 100644
--- a/drivers/i2c/busses/i2c-dln2.c
+++ b/drivers/i2c/busses/i2c-dln2.c
@@ -182,7 +182,7 @@ static const struct i2c_algorithm dln2_i2c_usb_algorithm = {
.functionality = dln2_i2c_func,
};
-static struct i2c_adapter_quirks dln2_i2c_quirks = {
+static const struct i2c_adapter_quirks dln2_i2c_quirks = {
.max_read_len = DLN2_I2C_MAX_XFER_SIZE,
.max_write_len = DLN2_I2C_MAX_XFER_SIZE,
};
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index eb3627f35d12..e242db43774b 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -118,7 +118,6 @@
#define SMBSLVSTS(p) (16 + (p)->smba) /* ICH3 and later */
#define SMBSLVCMD(p) (17 + (p)->smba) /* ICH3 and later */
#define SMBNTFDADD(p) (20 + (p)->smba) /* ICH3 and later */
-#define SMBNTFDDAT(p) (22 + (p)->smba) /* ICH3 and later */
/* PCI Address Constants */
#define SMBBAR 4
@@ -137,27 +136,27 @@
#define SBREG_SMBCTRL 0xc6000c
/* Host status bits for SMBPCISTS */
-#define SMBPCISTS_INTS 0x08
+#define SMBPCISTS_INTS BIT(3)
/* Control bits for SMBPCICTL */
-#define SMBPCICTL_INTDIS 0x0400
+#define SMBPCICTL_INTDIS BIT(10)
/* Host configuration bits for SMBHSTCFG */
-#define SMBHSTCFG_HST_EN 1
-#define SMBHSTCFG_SMB_SMI_EN 2
-#define SMBHSTCFG_I2C_EN 4
-#define SMBHSTCFG_SPD_WD 0x10
+#define SMBHSTCFG_HST_EN BIT(0)
+#define SMBHSTCFG_SMB_SMI_EN BIT(1)
+#define SMBHSTCFG_I2C_EN BIT(2)
+#define SMBHSTCFG_SPD_WD BIT(4)
/* TCO configuration bits for TCOCTL */
-#define TCOCTL_EN 0x0100
+#define TCOCTL_EN BIT(8)
/* Auxiliary status register bits, ICH4+ only */
-#define SMBAUXSTS_CRCE 1
-#define SMBAUXSTS_STCO 2
+#define SMBAUXSTS_CRCE BIT(0)
+#define SMBAUXSTS_STCO BIT(1)
/* Auxiliary control register bits, ICH4+ only */
-#define SMBAUXCTL_CRC 1
-#define SMBAUXCTL_E32B 2
+#define SMBAUXCTL_CRC BIT(0)
+#define SMBAUXCTL_E32B BIT(1)
/* Other settings */
#define MAX_RETRIES 400
@@ -172,27 +171,27 @@
#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
/* I801 Host Control register bits */
-#define SMBHSTCNT_INTREN 0x01
-#define SMBHSTCNT_KILL 0x02
-#define SMBHSTCNT_LAST_BYTE 0x20
-#define SMBHSTCNT_START 0x40
-#define SMBHSTCNT_PEC_EN 0x80 /* ICH3 and later */
+#define SMBHSTCNT_INTREN BIT(0)
+#define SMBHSTCNT_KILL BIT(1)
+#define SMBHSTCNT_LAST_BYTE BIT(5)
+#define SMBHSTCNT_START BIT(6)
+#define SMBHSTCNT_PEC_EN BIT(7) /* ICH3 and later */
/* I801 Hosts Status register bits */
-#define SMBHSTSTS_BYTE_DONE 0x80
-#define SMBHSTSTS_INUSE_STS 0x40
-#define SMBHSTSTS_SMBALERT_STS 0x20
-#define SMBHSTSTS_FAILED 0x10
-#define SMBHSTSTS_BUS_ERR 0x08
-#define SMBHSTSTS_DEV_ERR 0x04
-#define SMBHSTSTS_INTR 0x02
-#define SMBHSTSTS_HOST_BUSY 0x01
+#define SMBHSTSTS_BYTE_DONE BIT(7)
+#define SMBHSTSTS_INUSE_STS BIT(6)
+#define SMBHSTSTS_SMBALERT_STS BIT(5)
+#define SMBHSTSTS_FAILED BIT(4)
+#define SMBHSTSTS_BUS_ERR BIT(3)
+#define SMBHSTSTS_DEV_ERR BIT(2)
+#define SMBHSTSTS_INTR BIT(1)
+#define SMBHSTSTS_HOST_BUSY BIT(0)
-/* Host Notify Status registers bits */
-#define SMBSLVSTS_HST_NTFY_STS 1
+/* Host Notify Status register bits */
+#define SMBSLVSTS_HST_NTFY_STS BIT(0)
-/* Host Notify Command registers bits */
-#define SMBSLVCMD_HST_NTFY_INTREN 0x01
+/* Host Notify Command register bits */
+#define SMBSLVCMD_HST_NTFY_INTREN BIT(0)
#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \
SMBHSTSTS_DEV_ERR)
@@ -243,6 +242,7 @@ struct i801_priv {
struct i2c_adapter adapter;
unsigned long smba;
unsigned char original_hstcfg;
+ unsigned char original_slvcmd;
struct pci_dev *pci_dev;
unsigned int features;
@@ -269,20 +269,17 @@ struct i801_priv {
*/
bool acpi_reserved;
struct mutex acpi_lock;
- struct smbus_host_notify *host_notify;
};
-#define SMBHSTNTFY_SIZE 8
-
-#define FEATURE_SMBUS_PEC (1 << 0)
-#define FEATURE_BLOCK_BUFFER (1 << 1)
-#define FEATURE_BLOCK_PROC (1 << 2)
-#define FEATURE_I2C_BLOCK_READ (1 << 3)
-#define FEATURE_IRQ (1 << 4)
-#define FEATURE_HOST_NOTIFY (1 << 5)
+#define FEATURE_SMBUS_PEC BIT(0)
+#define FEATURE_BLOCK_BUFFER BIT(1)
+#define FEATURE_BLOCK_PROC BIT(2)
+#define FEATURE_I2C_BLOCK_READ BIT(3)
+#define FEATURE_IRQ BIT(4)
+#define FEATURE_HOST_NOTIFY BIT(5)
/* Not really a feature, but it's convenient to handle it as such */
-#define FEATURE_IDF (1 << 15)
-#define FEATURE_TCO (1 << 16)
+#define FEATURE_IDF BIT(15)
+#define FEATURE_TCO BIT(16)
static const char *i801_feature_names[] = {
"SMBus PEC",
@@ -582,12 +579,15 @@ static void i801_isr_byte_done(struct i801_priv *priv)
static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
{
unsigned short addr;
- unsigned int data;
addr = inb_p(SMBNTFDADD(priv)) >> 1;
- data = inw_p(SMBNTFDDAT(priv));
- i2c_handle_smbus_host_notify(priv->host_notify, addr, data);
+ /*
+ * With the tested platforms, reading SMBNTFDDAT (22 + (p)->smba)
+ * always returns 0. Our current implementation doesn't provide
+ * data, so we just ignore it.
+ */
+ i2c_handle_smbus_host_notify(&priv->adapter, addr);
/* clear Host Notify bit and return */
outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
@@ -950,23 +950,29 @@ static u32 i801_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_HOST_NOTIFY : 0);
}
-static int i801_enable_host_notify(struct i2c_adapter *adapter)
+static void i801_enable_host_notify(struct i2c_adapter *adapter)
{
struct i801_priv *priv = i2c_get_adapdata(adapter);
if (!(priv->features & FEATURE_HOST_NOTIFY))
- return -ENOTSUPP;
+ return;
- if (!priv->host_notify)
- priv->host_notify = i2c_setup_smbus_host_notify(adapter);
- if (!priv->host_notify)
- return -ENOMEM;
+ priv->original_slvcmd = inb_p(SMBSLVCMD(priv));
+
+ if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd))
+ outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd,
+ SMBSLVCMD(priv));
- outb_p(SMBSLVCMD_HST_NTFY_INTREN, SMBSLVCMD(priv));
/* clear Host Notify bit to allow a new notification */
outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
+}
- return 0;
+static void i801_disable_host_notify(struct i801_priv *priv)
+{
+ if (!(priv->features & FEATURE_HOST_NOTIFY))
+ return;
+
+ outb_p(priv->original_slvcmd, SMBSLVCMD(priv));
}
static const struct i2c_algorithm smbus_algorithm = {
@@ -1633,14 +1639,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
return err;
}
- /*
- * Enable Host Notify for chips that supports it.
- * It is done after i2c_add_adapter() so that we are sure the work queue
- * is not used if i2c_add_adapter() fails.
- */
- err = i801_enable_host_notify(&priv->adapter);
- if (err && err != -ENOTSUPP)
- dev_warn(&dev->dev, "Unable to enable SMBus Host Notify\n");
+ i801_enable_host_notify(&priv->adapter);
i801_probe_optional_slaves(priv);
/* We ignore errors - multiplexing is optional */
@@ -1663,6 +1662,7 @@ static void i801_remove(struct pci_dev *dev)
pm_runtime_forbid(&dev->dev);
pm_runtime_get_noresume(&dev->dev);
+ i801_disable_host_notify(priv);
i801_del_mux(priv);
i2c_del_adapter(&priv->adapter);
i801_acpi_remove(priv);
@@ -1690,11 +1690,8 @@ static int i801_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct i801_priv *priv = pci_get_drvdata(pci_dev);
- int err;
- err = i801_enable_host_notify(&priv->adapter);
- if (err && err != -ENOTSUPP)
- dev_warn(dev, "Unable to enable SMBus Host Notify\n");
+ i801_enable_host_notify(&priv->adapter);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
new file mode 100644
index 000000000000..c62b7cd475f8
--- /dev/null
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -0,0 +1,652 @@
+/*
+ * This is i.MX low power i2c controller driver.
+ *
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#define DRIVER_NAME "imx-lpi2c"
+
+#define LPI2C_PARAM 0x04 /* i2c RX/TX FIFO size */
+#define LPI2C_MCR 0x10 /* i2c contrl register */
+#define LPI2C_MSR 0x14 /* i2c status register */
+#define LPI2C_MIER 0x18 /* i2c interrupt enable */
+#define LPI2C_MCFGR0 0x20 /* i2c master configuration */
+#define LPI2C_MCFGR1 0x24 /* i2c master configuration */
+#define LPI2C_MCFGR2 0x28 /* i2c master configuration */
+#define LPI2C_MCFGR3 0x2C /* i2c master configuration */
+#define LPI2C_MCCR0 0x48 /* i2c master clk configuration */
+#define LPI2C_MCCR1 0x50 /* i2c master clk configuration */
+#define LPI2C_MFCR 0x58 /* i2c master FIFO control */
+#define LPI2C_MFSR 0x5C /* i2c master FIFO status */
+#define LPI2C_MTDR 0x60 /* i2c master TX data register */
+#define LPI2C_MRDR 0x70 /* i2c master RX data register */
+
+/* i2c command */
+#define TRAN_DATA 0X00
+#define RECV_DATA 0X01
+#define GEN_STOP 0X02
+#define RECV_DISCARD 0X03
+#define GEN_START 0X04
+#define START_NACK 0X05
+#define START_HIGH 0X06
+#define START_HIGH_NACK 0X07
+
+#define MCR_MEN BIT(0)
+#define MCR_RST BIT(1)
+#define MCR_DOZEN BIT(2)
+#define MCR_DBGEN BIT(3)
+#define MCR_RTF BIT(8)
+#define MCR_RRF BIT(9)
+#define MSR_TDF BIT(0)
+#define MSR_RDF BIT(1)
+#define MSR_SDF BIT(9)
+#define MSR_NDF BIT(10)
+#define MSR_ALF BIT(11)
+#define MSR_MBF BIT(24)
+#define MSR_BBF BIT(25)
+#define MIER_TDIE BIT(0)
+#define MIER_RDIE BIT(1)
+#define MIER_SDIE BIT(9)
+#define MIER_NDIE BIT(10)
+#define MCFGR1_AUTOSTOP BIT(8)
+#define MCFGR1_IGNACK BIT(9)
+#define MRDR_RXEMPTY BIT(14)
+
+#define I2C_CLK_RATIO 2
+#define CHUNK_DATA 256
+
+#define LPI2C_DEFAULT_RATE 100000
+#define STARDARD_MAX_BITRATE 400000
+#define FAST_MAX_BITRATE 1000000
+#define FAST_PLUS_MAX_BITRATE 3400000
+#define HIGHSPEED_MAX_BITRATE 5000000
+
+enum lpi2c_imx_mode {
+ STANDARD, /* 100+Kbps */
+ FAST, /* 400+Kbps */
+ FAST_PLUS, /* 1.0+Mbps */
+ HS, /* 3.4+Mbps */
+ ULTRA_FAST, /* 5.0+Mbps */
+};
+
+enum lpi2c_imx_pincfg {
+ TWO_PIN_OD,
+ TWO_PIN_OO,
+ TWO_PIN_PP,
+ FOUR_PIN_PP,
+};
+
+struct lpi2c_imx_struct {
+ struct i2c_adapter adapter;
+ struct clk *clk;
+ void __iomem *base;
+ __u8 *rx_buf;
+ __u8 *tx_buf;
+ struct completion complete;
+ unsigned int msglen;
+ unsigned int delivered;
+ unsigned int block_data;
+ unsigned int bitrate;
+ unsigned int txfifosize;
+ unsigned int rxfifosize;
+ enum lpi2c_imx_mode mode;
+};
+
+static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx,
+ unsigned int enable)
+{
+ writel(enable, lpi2c_imx->base + LPI2C_MIER);
+}
+
+static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned long orig_jiffies = jiffies;
+ unsigned int temp;
+
+ while (1) {
+ temp = readl(lpi2c_imx->base + LPI2C_MSR);
+
+ /* check for arbitration lost, clear if set */
+ if (temp & MSR_ALF) {
+ writel(temp, lpi2c_imx->base + LPI2C_MSR);
+ return -EAGAIN;
+ }
+
+ if (temp & (MSR_BBF | MSR_MBF))
+ break;
+
+ if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
+ dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n");
+ return -ETIMEDOUT;
+ }
+ schedule();
+ }
+
+ return 0;
+}
+
+static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned int bitrate = lpi2c_imx->bitrate;
+ enum lpi2c_imx_mode mode;
+
+ if (bitrate < STARDARD_MAX_BITRATE)
+ mode = STANDARD;
+ else if (bitrate < FAST_MAX_BITRATE)
+ mode = FAST;
+ else if (bitrate < FAST_PLUS_MAX_BITRATE)
+ mode = FAST_PLUS;
+ else if (bitrate < HIGHSPEED_MAX_BITRATE)
+ mode = HS;
+ else
+ mode = ULTRA_FAST;
+
+ lpi2c_imx->mode = mode;
+}
+
+static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx,
+ struct i2c_msg *msgs)
+{
+ unsigned int temp;
+ u8 read;
+
+ temp = readl(lpi2c_imx->base + LPI2C_MCR);
+ temp |= MCR_RRF | MCR_RTF;
+ writel(temp, lpi2c_imx->base + LPI2C_MCR);
+ writel(0x7f00, lpi2c_imx->base + LPI2C_MSR);
+
+ read = msgs->flags & I2C_M_RD;
+ temp = (msgs->addr << 1 | read) | (GEN_START << 8);
+ writel(temp, lpi2c_imx->base + LPI2C_MTDR);
+
+ return lpi2c_imx_bus_busy(lpi2c_imx);
+}
+
+static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned long orig_jiffies = jiffies;
+ unsigned int temp;
+
+ writel(GEN_STOP << 8, lpi2c_imx->base + LPI2C_MTDR);
+
+ do {
+ temp = readl(lpi2c_imx->base + LPI2C_MSR);
+ if (temp & MSR_SDF)
+ break;
+
+ if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
+ dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n");
+ break;
+ }
+ schedule();
+
+ } while (1);
+}
+
+/* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */
+static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ u8 prescale, filt, sethold, clkhi, clklo, datavd;
+ unsigned int clk_rate, clk_cycle;
+ enum lpi2c_imx_pincfg pincfg;
+ unsigned int temp;
+
+ lpi2c_imx_set_mode(lpi2c_imx);
+
+ clk_rate = clk_get_rate(lpi2c_imx->clk);
+ if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
+ filt = 0;
+ else
+ filt = 2;
+
+ for (prescale = 0; prescale <= 7; prescale++) {
+ clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate)
+ - 3 - (filt >> 1);
+ clkhi = (clk_cycle + I2C_CLK_RATIO) / (I2C_CLK_RATIO + 1);
+ clklo = clk_cycle - clkhi;
+ if (clklo < 64)
+ break;
+ }
+
+ if (prescale > 7)
+ return -EINVAL;
+
+ /* set MCFGR1: PINCFG, PRESCALE, IGNACK */
+ if (lpi2c_imx->mode == ULTRA_FAST)
+ pincfg = TWO_PIN_OO;
+ else
+ pincfg = TWO_PIN_OD;
+ temp = prescale | pincfg << 24;
+
+ if (lpi2c_imx->mode == ULTRA_FAST)
+ temp |= MCFGR1_IGNACK;
+
+ writel(temp, lpi2c_imx->base + LPI2C_MCFGR1);
+
+ /* set MCFGR2: FILTSDA, FILTSCL */
+ temp = (filt << 16) | (filt << 24);
+ writel(temp, lpi2c_imx->base + LPI2C_MCFGR2);
+
+ /* set MCCR: DATAVD, SETHOLD, CLKHI, CLKLO */
+ sethold = clkhi;
+ datavd = clkhi >> 1;
+ temp = datavd << 24 | sethold << 16 | clkhi << 8 | clklo;
+
+ if (lpi2c_imx->mode == HS)
+ writel(temp, lpi2c_imx->base + LPI2C_MCCR1);
+ else
+ writel(temp, lpi2c_imx->base + LPI2C_MCCR0);
+
+ return 0;
+}
+
+static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned int temp;
+ int ret;
+
+ ret = clk_enable(lpi2c_imx->clk);
+ if (ret)
+ return ret;
+
+ temp = MCR_RST;
+ writel(temp, lpi2c_imx->base + LPI2C_MCR);
+ writel(0, lpi2c_imx->base + LPI2C_MCR);
+
+ ret = lpi2c_imx_config(lpi2c_imx);
+ if (ret)
+ goto clk_disable;
+
+ temp = readl(lpi2c_imx->base + LPI2C_MCR);
+ temp |= MCR_MEN;
+ writel(temp, lpi2c_imx->base + LPI2C_MCR);
+
+ return 0;
+
+clk_disable:
+ clk_disable(lpi2c_imx->clk);
+
+ return ret;
+}
+
+static int lpi2c_imx_master_disable(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ u32 temp;
+
+ temp = readl(lpi2c_imx->base + LPI2C_MCR);
+ temp &= ~MCR_MEN;
+ writel(temp, lpi2c_imx->base + LPI2C_MCR);
+
+ clk_disable(lpi2c_imx->clk);
+
+ return 0;
+}
+
+static int lpi2c_imx_msg_complete(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned long timeout;
+
+ timeout = wait_for_completion_timeout(&lpi2c_imx->complete, HZ);
+
+ return timeout ? 0 : -ETIMEDOUT;
+}
+
+static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned long orig_jiffies = jiffies;
+ u32 txcnt;
+
+ do {
+ txcnt = readl(lpi2c_imx->base + LPI2C_MFSR) & 0xff;
+
+ if (readl(lpi2c_imx->base + LPI2C_MSR) & MSR_NDF) {
+ dev_dbg(&lpi2c_imx->adapter.dev, "NDF detected\n");
+ return -EIO;
+ }
+
+ if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
+ dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n");
+ return -ETIMEDOUT;
+ }
+ schedule();
+
+ } while (txcnt);
+
+ return 0;
+}
+
+static void lpi2c_imx_set_tx_watermark(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ writel(lpi2c_imx->txfifosize >> 1, lpi2c_imx->base + LPI2C_MFCR);
+}
+
+static void lpi2c_imx_set_rx_watermark(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned int temp, remaining;
+
+ remaining = lpi2c_imx->msglen - lpi2c_imx->delivered;
+
+ if (remaining > (lpi2c_imx->rxfifosize >> 1))
+ temp = lpi2c_imx->rxfifosize >> 1;
+ else
+ temp = 0;
+
+ writel(temp << 16, lpi2c_imx->base + LPI2C_MFCR);
+}
+
+static void lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned int data, txcnt;
+
+ txcnt = readl(lpi2c_imx->base + LPI2C_MFSR) & 0xff;
+
+ while (txcnt < lpi2c_imx->txfifosize) {
+ if (lpi2c_imx->delivered == lpi2c_imx->msglen)
+ break;
+
+ data = lpi2c_imx->tx_buf[lpi2c_imx->delivered++];
+ writel(data, lpi2c_imx->base + LPI2C_MTDR);
+ txcnt++;
+ }
+
+ if (lpi2c_imx->delivered < lpi2c_imx->msglen)
+ lpi2c_imx_intctrl(lpi2c_imx, MIER_TDIE | MIER_NDIE);
+ else
+ complete(&lpi2c_imx->complete);
+}
+
+static void lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx)
+{
+ unsigned int blocklen, remaining;
+ unsigned int temp, data;
+
+ do {
+ data = readl(lpi2c_imx->base + LPI2C_MRDR);
+ if (data & MRDR_RXEMPTY)
+ break;
+
+ lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff;
+ } while (1);
+
+ /*
+ * First byte is the length of remaining packet in the SMBus block
+ * data read. Add it to msgs->len.
+ */
+ if (lpi2c_imx->block_data) {
+ blocklen = lpi2c_imx->rx_buf[0];
+ lpi2c_imx->msglen += blocklen;
+ }
+
+ remaining = lpi2c_imx->msglen - lpi2c_imx->delivered;
+
+ if (!remaining) {
+ complete(&lpi2c_imx->complete);
+ return;
+ }
+
+ /* not finished, still waiting for rx data */
+ lpi2c_imx_set_rx_watermark(lpi2c_imx);
+
+ /* multiple receive commands */
+ if (lpi2c_imx->block_data) {
+ lpi2c_imx->block_data = 0;
+ temp = remaining;
+ temp |= (RECV_DATA << 8);
+ writel(temp, lpi2c_imx->base + LPI2C_MTDR);
+ } else if (!(lpi2c_imx->delivered & 0xff)) {
+ temp = (remaining > CHUNK_DATA ? CHUNK_DATA : remaining) - 1;
+ temp |= (RECV_DATA << 8);
+ writel(temp, lpi2c_imx->base + LPI2C_MTDR);
+ }
+
+ lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE);
+}
+
+static void lpi2c_imx_write(struct lpi2c_imx_struct *lpi2c_imx,
+ struct i2c_msg *msgs)
+{
+ lpi2c_imx->tx_buf = msgs->buf;
+ lpi2c_imx_set_tx_watermark(lpi2c_imx);
+ lpi2c_imx_write_txfifo(lpi2c_imx);
+}
+
+static void lpi2c_imx_read(struct lpi2c_imx_struct *lpi2c_imx,
+ struct i2c_msg *msgs)
+{
+ unsigned int temp;
+
+ lpi2c_imx->rx_buf = msgs->buf;
+ lpi2c_imx->block_data = msgs->flags & I2C_M_RECV_LEN;
+
+ lpi2c_imx_set_rx_watermark(lpi2c_imx);
+ temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1;
+ temp |= (RECV_DATA << 8);
+ writel(temp, lpi2c_imx->base + LPI2C_MTDR);
+
+ lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE);
+}
+
+static int lpi2c_imx_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(adapter);
+ unsigned int temp;
+ int i, result;
+
+ result = lpi2c_imx_master_enable(lpi2c_imx);
+ if (result)
+ return result;
+
+ for (i = 0; i < num; i++) {
+ result = lpi2c_imx_start(lpi2c_imx, &msgs[i]);
+ if (result)
+ goto disable;
+
+ /* quick smbus */
+ if (num == 1 && msgs[0].len == 0)
+ goto stop;
+
+ lpi2c_imx->delivered = 0;
+ lpi2c_imx->msglen = msgs[i].len;
+ init_completion(&lpi2c_imx->complete);
+
+ if (msgs[i].flags & I2C_M_RD)
+ lpi2c_imx_read(lpi2c_imx, &msgs[i]);
+ else
+ lpi2c_imx_write(lpi2c_imx, &msgs[i]);
+
+ result = lpi2c_imx_msg_complete(lpi2c_imx);
+ if (result)
+ goto stop;
+
+ if (!(msgs[i].flags & I2C_M_RD)) {
+ result = lpi2c_imx_txfifo_empty(lpi2c_imx);
+ if (result)
+ goto stop;
+ }
+ }
+
+stop:
+ lpi2c_imx_stop(lpi2c_imx);
+
+ temp = readl(lpi2c_imx->base + LPI2C_MSR);
+ if ((temp & MSR_NDF) && !result)
+ result = -EIO;
+
+disable:
+ lpi2c_imx_master_disable(lpi2c_imx);
+
+ dev_dbg(&lpi2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
+ (result < 0) ? "error" : "success msg",
+ (result < 0) ? result : num);
+
+ return (result < 0) ? result : num;
+}
+
+static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
+{
+ struct lpi2c_imx_struct *lpi2c_imx = dev_id;
+ unsigned int temp;
+
+ lpi2c_imx_intctrl(lpi2c_imx, 0);
+ temp = readl(lpi2c_imx->base + LPI2C_MSR);
+
+ if (temp & MSR_RDF)
+ lpi2c_imx_read_rxfifo(lpi2c_imx);
+
+ if (temp & MSR_TDF)
+ lpi2c_imx_write_txfifo(lpi2c_imx);
+
+ if (temp & MSR_NDF)
+ complete(&lpi2c_imx->complete);
+
+ return IRQ_HANDLED;
+}
+
+static u32 lpi2c_imx_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ I2C_FUNC_SMBUS_READ_BLOCK_DATA;
+}
+
+static struct i2c_algorithm lpi2c_imx_algo = {
+ .master_xfer = lpi2c_imx_xfer,
+ .functionality = lpi2c_imx_func,
+};
+
+static const struct of_device_id lpi2c_imx_of_match[] = {
+ { .compatible = "fsl,imx7ulp-lpi2c" },
+ { .compatible = "fsl,imx8dv-lpi2c" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match);
+
+static int lpi2c_imx_probe(struct platform_device *pdev)
+{
+ struct lpi2c_imx_struct *lpi2c_imx;
+ struct resource *res;
+ unsigned int temp;
+ int irq, ret;
+
+ lpi2c_imx = devm_kzalloc(&pdev->dev, sizeof(*lpi2c_imx), GFP_KERNEL);
+ if (!lpi2c_imx)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ lpi2c_imx->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(lpi2c_imx->base))
+ return PTR_ERR(lpi2c_imx->base);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "can't get irq number\n");
+ return irq;
+ }
+
+ lpi2c_imx->adapter.owner = THIS_MODULE;
+ lpi2c_imx->adapter.algo = &lpi2c_imx_algo;
+ lpi2c_imx->adapter.dev.parent = &pdev->dev;
+ lpi2c_imx->adapter.dev.of_node = pdev->dev.of_node;
+ strlcpy(lpi2c_imx->adapter.name, pdev->name,
+ sizeof(lpi2c_imx->adapter.name));
+
+ lpi2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(lpi2c_imx->clk)) {
+ dev_err(&pdev->dev, "can't get I2C peripheral clock\n");
+ return PTR_ERR(lpi2c_imx->clk);
+ }
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "clock-frequency", &lpi2c_imx->bitrate);
+ if (ret)
+ lpi2c_imx->bitrate = LPI2C_DEFAULT_RATE;
+
+ ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, 0,
+ pdev->name, lpi2c_imx);
+ if (ret) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", irq);
+ return ret;
+ }
+
+ i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx);
+ platform_set_drvdata(pdev, lpi2c_imx);
+
+ ret = clk_prepare_enable(lpi2c_imx->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "clk enable failed %d\n", ret);
+ return ret;
+ }
+
+ temp = readl(lpi2c_imx->base + LPI2C_PARAM);
+ lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
+ lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
+
+ clk_disable(lpi2c_imx->clk);
+
+ ret = i2c_add_adapter(&lpi2c_imx->adapter);
+ if (ret)
+ goto clk_unprepare;
+
+ dev_info(&lpi2c_imx->adapter.dev, "LPI2C adapter registered\n");
+
+ return 0;
+
+clk_unprepare:
+ clk_unprepare(lpi2c_imx->clk);
+
+ return ret;
+}
+
+static int lpi2c_imx_remove(struct platform_device *pdev)
+{
+ struct lpi2c_imx_struct *lpi2c_imx = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&lpi2c_imx->adapter);
+
+ clk_unprepare(lpi2c_imx->clk);
+
+ return 0;
+}
+
+static struct platform_driver lpi2c_imx_driver = {
+ .probe = lpi2c_imx_probe,
+ .remove = lpi2c_imx_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = lpi2c_imx_of_match,
+ },
+};
+
+module_platform_driver(lpi2c_imx_driver);
+
+MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
+MODULE_DESCRIPTION("I2C adapter driver for LPI2C bus");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
new file mode 100644
index 000000000000..d271e6a0954c
--- /dev/null
+++ b/drivers/i2c/busses/i2c-mlxcpld.c
@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Michael Shych <michaels@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+/* General defines */
+#define MLXPLAT_CPLD_LPC_I2C_BASE_ADDR 0x2000
+#define MLXCPLD_I2C_DEVICE_NAME "i2c_mlxcpld"
+#define MLXCPLD_I2C_VALID_FLAG (I2C_M_RECV_LEN | I2C_M_RD)
+#define MLXCPLD_I2C_BUS_NUM 1
+#define MLXCPLD_I2C_DATA_REG_SZ 36
+#define MLXCPLD_I2C_MAX_ADDR_LEN 4
+#define MLXCPLD_I2C_RETR_NUM 2
+#define MLXCPLD_I2C_XFER_TO 500000 /* usec */
+#define MLXCPLD_I2C_POLL_TIME 2000 /* usec */
+
+/* LPC I2C registers */
+#define MLXCPLD_LPCI2C_LPF_REG 0x0
+#define MLXCPLD_LPCI2C_CTRL_REG 0x1
+#define MLXCPLD_LPCI2C_HALF_CYC_REG 0x4
+#define MLXCPLD_LPCI2C_I2C_HOLD_REG 0x5
+#define MLXCPLD_LPCI2C_CMD_REG 0x6
+#define MLXCPLD_LPCI2C_NUM_DAT_REG 0x7
+#define MLXCPLD_LPCI2C_NUM_ADDR_REG 0x8
+#define MLXCPLD_LPCI2C_STATUS_REG 0x9
+#define MLXCPLD_LPCI2C_DATA_REG 0xa
+
+/* LPC I2C masks and parametres */
+#define MLXCPLD_LPCI2C_RST_SEL_MASK 0x1
+#define MLXCPLD_LPCI2C_TRANS_END 0x1
+#define MLXCPLD_LPCI2C_STATUS_NACK 0x10
+#define MLXCPLD_LPCI2C_NO_IND 0
+#define MLXCPLD_LPCI2C_ACK_IND 1
+#define MLXCPLD_LPCI2C_NACK_IND 2
+
+struct mlxcpld_i2c_curr_xfer {
+ u8 cmd;
+ u8 addr_width;
+ u8 data_len;
+ u8 msg_num;
+ struct i2c_msg *msg;
+};
+
+struct mlxcpld_i2c_priv {
+ struct i2c_adapter adap;
+ u32 base_addr;
+ struct mutex lock;
+ struct mlxcpld_i2c_curr_xfer xfer;
+ struct device *dev;
+};
+
+static void mlxcpld_i2c_lpc_write_buf(u8 *data, u8 len, u32 addr)
+{
+ int i;
+
+ for (i = 0; i < len - len % 4; i += 4)
+ outl(*(u32 *)(data + i), addr + i);
+ for (; i < len; ++i)
+ outb(*(data + i), addr + i);
+}
+
+static void mlxcpld_i2c_lpc_read_buf(u8 *data, u8 len, u32 addr)
+{
+ int i;
+
+ for (i = 0; i < len - len % 4; i += 4)
+ *(u32 *)(data + i) = inl(addr + i);
+ for (; i < len; ++i)
+ *(data + i) = inb(addr + i);
+}
+
+static void mlxcpld_i2c_read_comm(struct mlxcpld_i2c_priv *priv, u8 offs,
+ u8 *data, u8 datalen)
+{
+ u32 addr = priv->base_addr + offs;
+
+ switch (datalen) {
+ case 1:
+ *(data) = inb(addr);
+ break;
+ case 2:
+ *((u16 *)data) = inw(addr);
+ break;
+ case 3:
+ *((u16 *)data) = inw(addr);
+ *(data + 2) = inb(addr + 2);
+ break;
+ case 4:
+ *((u32 *)data) = inl(addr);
+ break;
+ default:
+ mlxcpld_i2c_lpc_read_buf(data, datalen, addr);
+ break;
+ }
+}
+
+static void mlxcpld_i2c_write_comm(struct mlxcpld_i2c_priv *priv, u8 offs,
+ u8 *data, u8 datalen)
+{
+ u32 addr = priv->base_addr + offs;
+
+ switch (datalen) {
+ case 1:
+ outb(*(data), addr);
+ break;
+ case 2:
+ outw(*((u16 *)data), addr);
+ break;
+ case 3:
+ outw(*((u16 *)data), addr);
+ outb(*(data + 2), addr + 2);
+ break;
+ case 4:
+ outl(*((u32 *)data), addr);
+ break;
+ default:
+ mlxcpld_i2c_lpc_write_buf(data, datalen, addr);
+ break;
+ }
+}
+
+/*
+ * Check validity of received i2c messages parameters.
+ * Returns 0 if OK, other - in case of invalid parameters.
+ */
+static int mlxcpld_i2c_check_msg_params(struct mlxcpld_i2c_priv *priv,
+ struct i2c_msg *msgs, int num)
+{
+ int i;
+
+ if (!num) {
+ dev_err(priv->dev, "Incorrect 0 num of messages\n");
+ return -EINVAL;
+ }
+
+ if (unlikely(msgs[0].addr > 0x7f)) {
+ dev_err(priv->dev, "Invalid address 0x%03x\n",
+ msgs[0].addr);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < num; ++i) {
+ if (unlikely(!msgs[i].buf)) {
+ dev_err(priv->dev, "Invalid buf in msg[%d]\n",
+ i);
+ return -EINVAL;
+ }
+ if (unlikely(msgs[0].addr != msgs[i].addr)) {
+ dev_err(priv->dev, "Invalid addr in msg[%d]\n",
+ i);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Check if transfer is completed and status of operation.
+ * Returns 0 - transfer completed (both ACK or NACK),
+ * negative - transfer isn't finished.
+ */
+static int mlxcpld_i2c_check_status(struct mlxcpld_i2c_priv *priv, int *status)
+{
+ u8 val;
+
+ mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_STATUS_REG, &val, 1);
+
+ if (val & MLXCPLD_LPCI2C_TRANS_END) {
+ if (val & MLXCPLD_LPCI2C_STATUS_NACK)
+ /*
+ * The slave is unable to accept the data. No such
+ * slave, command not understood, or unable to accept
+ * any more data.
+ */
+ *status = MLXCPLD_LPCI2C_NACK_IND;
+ else
+ *status = MLXCPLD_LPCI2C_ACK_IND;
+ return 0;
+ }
+ *status = MLXCPLD_LPCI2C_NO_IND;
+
+ return -EIO;
+}
+
+static void mlxcpld_i2c_set_transf_data(struct mlxcpld_i2c_priv *priv,
+ struct i2c_msg *msgs, int num,
+ u8 comm_len)
+{
+ priv->xfer.msg = msgs;
+ priv->xfer.msg_num = num;
+
+ /*
+ * All upper layers currently are never use transfer with more than
+ * 2 messages. Actually, it's also not so relevant in Mellanox systems
+ * because of HW limitation. Max size of transfer is not more than 32
+ * bytes in the current x86 LPCI2C bridge.
+ */
+ priv->xfer.cmd = msgs[num - 1].flags & I2C_M_RD;
+
+ if (priv->xfer.cmd == I2C_M_RD && comm_len != msgs[0].len) {
+ priv->xfer.addr_width = msgs[0].len;
+ priv->xfer.data_len = comm_len - priv->xfer.addr_width;
+ } else {
+ priv->xfer.addr_width = 0;
+ priv->xfer.data_len = comm_len;
+ }
+}
+
+/* Reset CPLD LPCI2C block */
+static void mlxcpld_i2c_reset(struct mlxcpld_i2c_priv *priv)
+{
+ u8 val;
+
+ mutex_lock(&priv->lock);
+
+ mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_CTRL_REG, &val, 1);
+ val &= ~MLXCPLD_LPCI2C_RST_SEL_MASK;
+ mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_CTRL_REG, &val, 1);
+
+ mutex_unlock(&priv->lock);
+}
+
+/* Make sure the CPLD is ready to start transmitting. */
+static int mlxcpld_i2c_check_busy(struct mlxcpld_i2c_priv *priv)
+{
+ u8 val;
+
+ mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_STATUS_REG, &val, 1);
+
+ if (val & MLXCPLD_LPCI2C_TRANS_END)
+ return 0;
+
+ return -EIO;
+}
+
+static int mlxcpld_i2c_wait_for_free(struct mlxcpld_i2c_priv *priv)
+{
+ int timeout = 0;
+
+ do {
+ if (!mlxcpld_i2c_check_busy(priv))
+ break;
+ usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
+ timeout += MLXCPLD_I2C_POLL_TIME;
+ } while (timeout <= MLXCPLD_I2C_XFER_TO);
+
+ if (timeout > MLXCPLD_I2C_XFER_TO)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+/*
+ * Wait for master transfer to complete.
+ * It puts current process to sleep until we get interrupt or timeout expires.
+ * Returns the number of transferred or read bytes or error (<0).
+ */
+static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
+{
+ int status, i, timeout = 0;
+ u8 datalen;
+
+ do {
+ usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
+ if (!mlxcpld_i2c_check_status(priv, &status))
+ break;
+ timeout += MLXCPLD_I2C_POLL_TIME;
+ } while (status == 0 && timeout < MLXCPLD_I2C_XFER_TO);
+
+ switch (status) {
+ case MLXCPLD_LPCI2C_NO_IND:
+ return -ETIMEDOUT;
+
+ case MLXCPLD_LPCI2C_ACK_IND:
+ if (priv->xfer.cmd != I2C_M_RD)
+ return (priv->xfer.addr_width + priv->xfer.data_len);
+
+ if (priv->xfer.msg_num == 1)
+ i = 0;
+ else
+ i = 1;
+
+ if (!priv->xfer.msg[i].buf)
+ return -EINVAL;
+
+ /*
+ * Actual read data len will be always the same as
+ * requested len. 0xff (line pull-up) will be returned
+ * if slave has no data to return. Thus don't read
+ * MLXCPLD_LPCI2C_NUM_DAT_REG reg from CPLD.
+ */
+ datalen = priv->xfer.data_len;
+
+ mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_DATA_REG,
+ priv->xfer.msg[i].buf, datalen);
+
+ return datalen;
+
+ case MLXCPLD_LPCI2C_NACK_IND:
+ return -ENXIO;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static void mlxcpld_i2c_xfer_msg(struct mlxcpld_i2c_priv *priv)
+{
+ int i, len = 0;
+ u8 cmd;
+
+ mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG,
+ &priv->xfer.data_len, 1);
+ mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_ADDR_REG,
+ &priv->xfer.addr_width, 1);
+
+ for (i = 0; i < priv->xfer.msg_num; i++) {
+ if ((priv->xfer.msg[i].flags & I2C_M_RD) != I2C_M_RD) {
+ /* Don't write to CPLD buffer in read transaction */
+ mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_DATA_REG +
+ len, priv->xfer.msg[i].buf,
+ priv->xfer.msg[i].len);
+ len += priv->xfer.msg[i].len;
+ }
+ }
+
+ /*
+ * Set target slave address with command for master transfer.
+ * It should be latest executed function before CPLD transaction.
+ */
+ cmd = (priv->xfer.msg[0].addr << 1) | priv->xfer.cmd;
+ mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_CMD_REG, &cmd, 1);
+}
+
+/*
+ * Generic lpc-i2c transfer.
+ * Returns the number of processed messages or error (<0).
+ */
+static int mlxcpld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct mlxcpld_i2c_priv *priv = i2c_get_adapdata(adap);
+ u8 comm_len = 0;
+ int i, err;
+
+ err = mlxcpld_i2c_check_msg_params(priv, msgs, num);
+ if (err) {
+ dev_err(priv->dev, "Incorrect message\n");
+ return err;
+ }
+
+ for (i = 0; i < num; ++i)
+ comm_len += msgs[i].len;
+
+ /* Check bus state */
+ if (mlxcpld_i2c_wait_for_free(priv)) {
+ dev_err(priv->dev, "LPCI2C bridge is busy\n");
+
+ /*
+ * Usually it means something serious has happened.
+ * We can not have unfinished previous transfer
+ * so it doesn't make any sense to try to stop it.
+ * Probably we were not able to recover from the
+ * previous error.
+ * The only reasonable thing - is soft reset.
+ */
+ mlxcpld_i2c_reset(priv);
+ if (mlxcpld_i2c_check_busy(priv)) {
+ dev_err(priv->dev, "LPCI2C bridge is busy after reset\n");
+ return -EIO;
+ }
+ }
+
+ mlxcpld_i2c_set_transf_data(priv, msgs, num, comm_len);
+
+ mutex_lock(&priv->lock);
+
+ /* Do real transfer. Can't fail */
+ mlxcpld_i2c_xfer_msg(priv);
+
+ /* Wait for transaction complete */
+ err = mlxcpld_i2c_wait_for_tc(priv);
+
+ mutex_unlock(&priv->lock);
+
+ return err < 0 ? err : num;
+}
+
+static u32 mlxcpld_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm mlxcpld_i2c_algo = {
+ .master_xfer = mlxcpld_i2c_xfer,
+ .functionality = mlxcpld_i2c_func
+};
+
+static struct i2c_adapter_quirks mlxcpld_i2c_quirks = {
+ .flags = I2C_AQ_COMB_WRITE_THEN_READ,
+ .max_read_len = MLXCPLD_I2C_DATA_REG_SZ - MLXCPLD_I2C_MAX_ADDR_LEN,
+ .max_write_len = MLXCPLD_I2C_DATA_REG_SZ,
+ .max_comb_1st_msg_len = 4,
+};
+
+static struct i2c_adapter mlxcpld_i2c_adapter = {
+ .owner = THIS_MODULE,
+ .name = "i2c-mlxcpld",
+ .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+ .algo = &mlxcpld_i2c_algo,
+ .quirks = &mlxcpld_i2c_quirks,
+ .retries = MLXCPLD_I2C_RETR_NUM,
+ .nr = MLXCPLD_I2C_BUS_NUM,
+};
+
+static int mlxcpld_i2c_probe(struct platform_device *pdev)
+{
+ struct mlxcpld_i2c_priv *priv;
+ int err;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ mutex_init(&priv->lock);
+ platform_set_drvdata(pdev, priv);
+
+ priv->dev = &pdev->dev;
+
+ /* Register with i2c layer */
+ mlxcpld_i2c_adapter.timeout = usecs_to_jiffies(MLXCPLD_I2C_XFER_TO);
+ priv->adap = mlxcpld_i2c_adapter;
+ priv->adap.dev.parent = &pdev->dev;
+ priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR;
+ i2c_set_adapdata(&priv->adap, priv);
+
+ err = i2c_add_numbered_adapter(&priv->adap);
+ if (err)
+ mutex_destroy(&priv->lock);
+
+ return err;
+}
+
+static int mlxcpld_i2c_remove(struct platform_device *pdev)
+{
+ struct mlxcpld_i2c_priv *priv = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&priv->adap);
+ mutex_destroy(&priv->lock);
+
+ return 0;
+}
+
+static struct platform_driver mlxcpld_i2c_driver = {
+ .probe = mlxcpld_i2c_probe,
+ .remove = mlxcpld_i2c_remove,
+ .driver = {
+ .name = MLXCPLD_I2C_DEVICE_NAME,
+ },
+};
+
+module_platform_driver(mlxcpld_i2c_driver);
+
+MODULE_AUTHOR("Michael Shych <michaels@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox I2C-CPLD controller driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:i2c-mlxcpld");
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 5e63b17f935d..3d10f1a802be 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -36,24 +36,6 @@ static bool octeon_i2c_test_iflg(struct octeon_i2c *i2c)
return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG);
}
-static bool octeon_i2c_test_ready(struct octeon_i2c *i2c, bool *first)
-{
- if (octeon_i2c_test_iflg(i2c))
- return true;
-
- if (*first) {
- *first = false;
- return false;
- }
-
- /*
- * IRQ has signaled an event but IFLG hasn't changed.
- * Sleep and retry once.
- */
- usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT);
- return octeon_i2c_test_iflg(i2c);
-}
-
/**
* octeon_i2c_wait - wait for the IFLG to be set
* @i2c: The struct octeon_i2c
@@ -63,7 +45,6 @@ static bool octeon_i2c_test_ready(struct octeon_i2c *i2c, bool *first)
static int octeon_i2c_wait(struct octeon_i2c *i2c)
{
long time_left;
- bool first = true;
/*
* Some chip revisions don't assert the irq in the interrupt
@@ -80,7 +61,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c)
}
i2c->int_enable(i2c);
- time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_ready(i2c, &first),
+ time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_iflg(i2c),
i2c->adap.timeout);
i2c->int_disable(i2c);
@@ -102,25 +83,6 @@ static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c)
return (__raw_readq(i2c->twsi_base + SW_TWSI(i2c)) & SW_TWSI_V) == 0;
}
-static bool octeon_i2c_hlc_test_ready(struct octeon_i2c *i2c, bool *first)
-{
- /* check if valid bit is cleared */
- if (octeon_i2c_hlc_test_valid(i2c))
- return true;
-
- if (*first) {
- *first = false;
- return false;
- }
-
- /*
- * IRQ has signaled an event but valid bit isn't cleared.
- * Sleep and retry once.
- */
- usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT);
- return octeon_i2c_hlc_test_valid(i2c);
-}
-
static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c)
{
/* clear ST/TS events, listen for neither */
@@ -176,7 +138,6 @@ static void octeon_i2c_hlc_disable(struct octeon_i2c *i2c)
*/
static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
{
- bool first = true;
int time_left;
/*
@@ -195,7 +156,7 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
i2c->hlc_int_enable(i2c);
time_left = wait_event_timeout(i2c->queue,
- octeon_i2c_hlc_test_ready(i2c, &first),
+ octeon_i2c_hlc_test_valid(i2c),
i2c->adap.timeout);
i2c->hlc_int_disable(i2c);
if (!time_left)
@@ -789,6 +750,9 @@ static void octeon_i2c_prepare_recovery(struct i2c_adapter *adap)
struct octeon_i2c *i2c = i2c_get_adapdata(adap);
octeon_i2c_hlc_disable(i2c);
+ octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_RST, 0);
+ /* wait for software reset to settle */
+ udelay(5);
/*
* Bring control register to a good state regardless
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
index 417464e9ea2a..004deb96afe3 100644
--- a/drivers/i2c/busses/i2c-pxa-pci.c
+++ b/drivers/i2c/busses/i2c-pxa-pci.c
@@ -1,9 +1,13 @@
/*
+ * CE4100 PCI-I2C glue code for PXA's driver
+ * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ * License: GPL v2
+ *
* The CE4100's I2C device is more or less the same one as found on PXA.
* It does not support slave mode, the register slightly moved. This PCI
* device provides three bars, every contains a single I2C controller.
*/
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/i2c/pxa-i2c.h>
@@ -134,35 +138,17 @@ err_mem:
return ret;
}
-static void ce4100_i2c_remove(struct pci_dev *dev)
-{
- struct ce4100_devices *sds;
- unsigned int i;
-
- sds = pci_get_drvdata(dev);
-
- for (i = 0; i < ARRAY_SIZE(sds->pdev); i++)
- platform_device_unregister(sds->pdev[i]);
-
- pci_disable_device(dev);
- kfree(sds);
-}
-
static const struct pci_device_id ce4100_i2c_devices[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
{ },
};
-MODULE_DEVICE_TABLE(pci, ce4100_i2c_devices);
static struct pci_driver ce4100_i2c_driver = {
+ .driver = {
+ .suppress_bind_attrs = true,
+ },
.name = "ce4100_i2c",
.id_table = ce4100_i2c_devices,
.probe = ce4100_i2c_probe,
- .remove = ce4100_i2c_remove,
};
-
-module_pci_driver(ce4100_i2c_driver);
-
-MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
+builtin_pci_driver(ce4100_i2c_driver);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index e28b825b0433..6cf333ecc8b8 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -48,6 +48,8 @@ struct pxa_reg_layout {
u32 isar;
u32 ilcr;
u32 iwcr;
+ u32 fm;
+ u32 hs;
};
enum pxa_i2c_types {
@@ -55,8 +57,12 @@ enum pxa_i2c_types {
REGS_PXA3XX,
REGS_CE4100,
REGS_PXA910,
+ REGS_A3700,
};
+#define ICR_BUSMODE_FM (1 << 16) /* shifted fast mode for armada-3700 */
+#define ICR_BUSMODE_HS (1 << 17) /* shifted high speed mode for armada-3700 */
+
/*
* I2C registers definitions
*/
@@ -91,6 +97,15 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.ilcr = 0x28,
.iwcr = 0x30,
},
+ [REGS_A3700] = {
+ .ibmr = 0x00,
+ .idbr = 0x04,
+ .icr = 0x08,
+ .isr = 0x0c,
+ .isar = 0x10,
+ .fm = ICR_BUSMODE_FM,
+ .hs = ICR_BUSMODE_HS,
+ },
};
static const struct platform_device_id i2c_pxa_id_table[] = {
@@ -98,6 +113,7 @@ static const struct platform_device_id i2c_pxa_id_table[] = {
{ "pxa3xx-pwri2c", REGS_PXA3XX },
{ "ce4100-i2c", REGS_CE4100 },
{ "pxa910-i2c", REGS_PXA910 },
+ { "armada-3700-i2c", REGS_A3700 },
{ },
};
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -193,6 +209,8 @@ struct pxa_i2c {
unsigned char master_code;
unsigned long rate;
bool highmode_enter;
+ u32 fm_mask;
+ u32 hs_mask;
};
#define _IBMR(i2c) ((i2c)->reg_ibmr)
@@ -503,8 +521,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
writel(i2c->slave_addr, _ISAR(i2c));
/* set control register values */
- writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
- writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c));
+ writel(I2C_ICR_INIT | (i2c->fast_mode ? i2c->fm_mask : 0), _ICR(i2c));
+ writel(readl(_ICR(i2c)) | (i2c->high_mode ? i2c->hs_mask : 0), _ICR(i2c));
#ifdef CONFIG_I2C_PXA_SLAVE
dev_info(&i2c->adap.dev, "Enabling slave mode\n");
@@ -1137,6 +1155,7 @@ static const struct of_device_id i2c_pxa_dt_ids[] = {
{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
+ { .compatible = "marvell,armada-3700-i2c", .data = (void *)REGS_A3700 },
{}
};
MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
@@ -1234,6 +1253,9 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
+ i2c->fm_mask = pxa_reg_layout[i2c_type].fm ? : ICR_FM;
+ i2c->hs_mask = pxa_reg_layout[i2c_type].hs ? : ICR_HS;
+
if (i2c_type != REGS_CE4100)
i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index a8497cfdae6f..1902d8ac9753 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -14,6 +14,7 @@
*
*/
+#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -132,6 +133,10 @@
/* Max timeout in ms for 32k bytes */
#define TOUT_MAX 300
+/* Default values. Use these if FW query fails */
+#define DEFAULT_CLK_FREQ 100000
+#define DEFAULT_SRC_CLK 20000000
+
struct qup_i2c_block {
int count;
int pos;
@@ -525,6 +530,33 @@ static int qup_i2c_get_data_len(struct qup_i2c_dev *qup)
return data_len;
}
+static bool qup_i2c_check_msg_len(struct i2c_msg *msg)
+{
+ return ((msg->flags & I2C_M_RD) && (msg->flags & I2C_M_RECV_LEN));
+}
+
+static int qup_i2c_set_tags_smb(u16 addr, u8 *tags, struct qup_i2c_dev *qup,
+ struct i2c_msg *msg)
+{
+ int len = 0;
+
+ if (msg->len > 1) {
+ tags[len++] = QUP_TAG_V2_DATARD_STOP;
+ tags[len++] = qup_i2c_get_data_len(qup) - 1;
+ } else {
+ tags[len++] = QUP_TAG_V2_START;
+ tags[len++] = addr & 0xff;
+
+ if (msg->flags & I2C_M_TEN)
+ tags[len++] = addr >> 8;
+
+ tags[len++] = QUP_TAG_V2_DATARD;
+ /* Read 1 byte indicating the length of the SMBus message */
+ tags[len++] = 1;
+ }
+ return len;
+}
+
static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
struct i2c_msg *msg, int is_dma)
{
@@ -534,6 +566,10 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
int last = (qup->blk.pos == (qup->blk.count - 1)) && (qup->is_last);
+ /* Handle tags for SMBus block read */
+ if (qup_i2c_check_msg_len(msg))
+ return qup_i2c_set_tags_smb(addr, tags, qup, msg);
+
if (qup->blk.pos == 0) {
tags[len++] = QUP_TAG_V2_START;
tags[len++] = addr & 0xff;
@@ -1056,9 +1092,17 @@ static int qup_i2c_read_fifo_v2(struct qup_i2c_dev *qup,
struct i2c_msg *msg)
{
u32 val;
- int idx, pos = 0, ret = 0, total;
+ int idx, pos = 0, ret = 0, total, msg_offset = 0;
+ /*
+ * If the message length is already read in
+ * the first byte of the buffer, account for
+ * that by setting the offset
+ */
+ if (qup_i2c_check_msg_len(msg) && (msg->len > 1))
+ msg_offset = 1;
total = qup_i2c_get_data_len(qup);
+ total -= msg_offset;
/* 2 extra bytes for read tags */
while (pos < (total + 2)) {
@@ -1078,8 +1122,8 @@ static int qup_i2c_read_fifo_v2(struct qup_i2c_dev *qup,
if (pos >= (total + 2))
goto out;
-
- msg->buf[qup->pos++] = val & 0xff;
+ msg->buf[qup->pos + msg_offset] = val & 0xff;
+ qup->pos++;
}
}
@@ -1119,6 +1163,20 @@ static int qup_i2c_read_one_v2(struct qup_i2c_dev *qup, struct i2c_msg *msg)
goto err;
qup->blk.pos++;
+
+ /* Handle SMBus block read length */
+ if (qup_i2c_check_msg_len(msg) && (msg->len == 1)) {
+ if (msg->buf[0] > I2C_SMBUS_BLOCK_MAX) {
+ ret = -EPROTO;
+ goto err;
+ }
+ msg->len += msg->buf[0];
+ qup->pos = 0;
+ qup_i2c_set_blk_data(qup, msg);
+ /* set tag length for block read */
+ qup->blk.tx_tag_len = 2;
+ qup_i2c_set_read_mode_v2(qup, msg->buf[0]);
+ }
} while (qup->blk.pos < qup->blk.count);
err:
@@ -1204,6 +1262,11 @@ static int qup_i2c_xfer(struct i2c_adapter *adap,
goto out;
}
+ if (qup_i2c_check_msg_len(&msgs[idx])) {
+ ret = -EINVAL;
+ goto out;
+ }
+
if (msgs[idx].flags & I2C_M_RD)
ret = qup_i2c_read_one(qup, &msgs[idx]);
else
@@ -1358,14 +1421,13 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup)
static int qup_i2c_probe(struct platform_device *pdev)
{
static const int blk_sizes[] = {4, 16, 32};
- struct device_node *node = pdev->dev.of_node;
struct qup_i2c_dev *qup;
unsigned long one_bit_t;
struct resource *res;
u32 io_mode, hw_ver, size;
int ret, fs_div, hs_div;
- int src_clk_freq;
- u32 clk_freq = 100000;
+ u32 src_clk_freq = DEFAULT_SRC_CLK;
+ u32 clk_freq = DEFAULT_CLK_FREQ;
int blocks;
qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
@@ -1376,7 +1438,11 @@ static int qup_i2c_probe(struct platform_device *pdev)
init_completion(&qup->xfer);
platform_set_drvdata(pdev, qup);
- of_property_read_u32(node, "clock-frequency", &clk_freq);
+ ret = device_property_read_u32(qup->dev, "clock-frequency", &clk_freq);
+ if (ret) {
+ dev_notice(qup->dev, "using default clock-frequency %d",
+ DEFAULT_CLK_FREQ);
+ }
if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
qup->adap.algo = &qup_i2c_algo;
@@ -1452,20 +1518,30 @@ nodma:
return qup->irq;
}
- qup->clk = devm_clk_get(qup->dev, "core");
- if (IS_ERR(qup->clk)) {
- dev_err(qup->dev, "Could not get core clock\n");
- return PTR_ERR(qup->clk);
- }
+ if (has_acpi_companion(qup->dev)) {
+ ret = device_property_read_u32(qup->dev,
+ "src-clock-hz", &src_clk_freq);
+ if (ret) {
+ dev_notice(qup->dev, "using default src-clock-hz %d",
+ DEFAULT_SRC_CLK);
+ }
+ ACPI_COMPANION_SET(&qup->adap.dev, ACPI_COMPANION(qup->dev));
+ } else {
+ qup->clk = devm_clk_get(qup->dev, "core");
+ if (IS_ERR(qup->clk)) {
+ dev_err(qup->dev, "Could not get core clock\n");
+ return PTR_ERR(qup->clk);
+ }
- qup->pclk = devm_clk_get(qup->dev, "iface");
- if (IS_ERR(qup->pclk)) {
- dev_err(qup->dev, "Could not get iface clock\n");
- return PTR_ERR(qup->pclk);
+ qup->pclk = devm_clk_get(qup->dev, "iface");
+ if (IS_ERR(qup->pclk)) {
+ dev_err(qup->dev, "Could not get iface clock\n");
+ return PTR_ERR(qup->pclk);
+ }
+ qup_i2c_enable_clocks(qup);
+ src_clk_freq = clk_get_rate(qup->clk);
}
- qup_i2c_enable_clocks(qup);
-
/*
* Bootloaders might leave a pending interrupt on certain QUP's,
* so we reset the core before registering for interrupts.
@@ -1512,7 +1588,6 @@ nodma:
size = QUP_INPUT_FIFO_SIZE(io_mode);
qup->in_fifo_sz = qup->in_blk_sz * (2 << size);
- src_clk_freq = clk_get_rate(qup->clk);
fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
hs_div = 3;
qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);
@@ -1631,6 +1706,14 @@ static const struct of_device_id qup_i2c_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, qup_i2c_dt_match);
+#if IS_ENABLED(CONFIG_ACPI)
+static const struct acpi_device_id qup_i2c_acpi_match[] = {
+ { "QCOM8010"},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, qup_i2c_acpi_match);
+#endif
+
static struct platform_driver qup_i2c_driver = {
.probe = qup_i2c_probe,
.remove = qup_i2c_remove,
@@ -1638,6 +1721,7 @@ static struct platform_driver qup_i2c_driver = {
.name = "i2c_qup",
.pm = &qup_i2c_qup_pm_ops,
.of_match_table = qup_i2c_dt_match,
+ .acpi_match_table = ACPI_PTR(qup_i2c_acpi_match),
},
};
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 726615e54f2a..26f2ff22e97e 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -793,7 +793,6 @@ static const struct i2c_algorithm rcar_i2c_algo = {
};
static const struct of_device_id rcar_i2c_dt_ids[] = {
- { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 },
@@ -803,6 +802,10 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
+ { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 }, /* Deprecated */
+ { .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
+ { .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
+ { .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },
{},
};
MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 192f36f00e4d..3d9ebe6e5716 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -827,7 +827,6 @@ static const struct sh_mobile_dt_config r8a7740_dt_config = {
};
static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
- { .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
{ .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config },
{ .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config },
@@ -835,8 +834,11 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
{ .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7793", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7794", .data = &fast_clock_dt_config },
+ { .compatible = "renesas,rcar-gen2-iic", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7795", .data = &fast_clock_dt_config },
+ { .compatible = "renesas,rcar-gen3-iic", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-sh73a0", .data = &fast_clock_dt_config },
+ { .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
{},
};
MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids);
diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c
index db9105e52c79..beee31892295 100644
--- a/drivers/i2c/busses/i2c-uniphier-f.c
+++ b/drivers/i2c/busses/i2c-uniphier-f.c
@@ -528,7 +528,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
if (!clk_rate) {
dev_err(dev, "input clock rate should not be zero\n");
ret = -EINVAL;
- goto err;
+ goto disable_clk;
}
init_completion(&priv->comp);
@@ -547,11 +547,11 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
pdev->name, priv);
if (ret) {
dev_err(dev, "failed to request irq %d\n", irq);
- goto err;
+ goto disable_clk;
}
ret = i2c_add_adapter(&priv->adap);
-err:
+disable_clk:
if (ret)
clk_disable_unprepare(priv->clk);
diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c
index 56e92af46ddc..777c0fe93653 100644
--- a/drivers/i2c/busses/i2c-uniphier.c
+++ b/drivers/i2c/busses/i2c-uniphier.c
@@ -373,7 +373,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
if (!clk_rate) {
dev_err(dev, "input clock rate should not be zero\n");
ret = -EINVAL;
- goto err;
+ goto disable_clk;
}
init_completion(&priv->comp);
@@ -392,11 +392,11 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
priv);
if (ret) {
dev_err(dev, "failed to request irq %d\n", irq);
- goto err;
+ goto disable_clk;
}
ret = i2c_add_adapter(&priv->adap);
-err:
+disable_clk:
if (ret)
clk_disable_unprepare(priv->clk);
diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c
index 543456a0a338..e4be86b3de9a 100644
--- a/drivers/i2c/busses/i2c-viperboard.c
+++ b/drivers/i2c/busses/i2c-viperboard.c
@@ -354,7 +354,7 @@ static const struct i2c_algorithm vprbrd_algorithm = {
.functionality = vprbrd_i2c_func,
};
-static struct i2c_adapter_quirks vprbrd_quirks = {
+static const struct i2c_adapter_quirks vprbrd_quirks = {
.max_read_len = 2048,
.max_write_len = 2048,
};
diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c
index e29ff37a43bd..84a8b2eccffb 100644
--- a/drivers/i2c/busses/i2c-xlp9xx.c
+++ b/drivers/i2c/busses/i2c-xlp9xx.c
@@ -393,6 +393,7 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev)
init_completion(&priv->msg_complete);
priv->adapter.dev.parent = &pdev->dev;
priv->adapter.algo = &xlp9xx_i2c_algo;
+ ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&pdev->dev));
priv->adapter.dev.of_node = pdev->dev.of_node;
priv->dev = &pdev->dev;
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b432b64e307a..3de95a29024c 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -65,6 +65,9 @@
#define I2C_ADDR_OFFSET_TEN_BIT 0xa000
#define I2C_ADDR_OFFSET_SLAVE 0x1000
+#define I2C_ADDR_7BITS_MAX 0x77
+#define I2C_ADDR_7BITS_COUNT (I2C_ADDR_7BITS_MAX + 1)
+
/* core_lock protects i2c_adapter_idr, and guarantees
that device detection, deletion of detected devices, and attach_adapter
calls are serialized */
@@ -77,9 +80,10 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
static bool is_registered;
-void i2c_transfer_trace_reg(void)
+int i2c_transfer_trace_reg(void)
{
static_key_slow_inc(&i2c_trace_msg);
+ return 0;
}
void i2c_transfer_trace_unreg(void)
@@ -676,9 +680,12 @@ static inline int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
/* ------------------------------------------------------------------------- */
-static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
+ if (!(id && client))
+ return NULL;
+
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0)
return id;
@@ -686,17 +693,16 @@ static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
}
return NULL;
}
+EXPORT_SYMBOL_GPL(i2c_match_id);
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;
- if (!client)
- return 0;
/* Attempt an OF style match */
- if (of_driver_match_device(dev, drv))
+ if (i2c_of_match_device(drv->of_match_table, client))
return 1;
/* Then ACPI style match */
@@ -704,9 +710,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
return 1;
driver = to_i2c_driver(drv);
- /* match on an id table if there is one */
- if (driver->id_table)
- return i2c_match_id(driver->id_table, client) != NULL;
+
+ /* Finally an I2C match */
+ if (i2c_match_id(driver->id_table, client))
+ return 1;
return 0;
}
@@ -893,6 +900,25 @@ static void i2c_init_recovery(struct i2c_adapter *adap)
adap->bus_recovery_info = NULL;
}
+static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client)
+{
+ struct i2c_adapter *adap = client->adapter;
+ unsigned int irq;
+
+ if (!adap->host_notify_domain)
+ return -ENXIO;
+
+ if (client->flags & I2C_CLIENT_TEN)
+ return -EINVAL;
+
+ irq = irq_find_mapping(adap->host_notify_domain, client->addr);
+ if (!irq)
+ irq = irq_create_mapping(adap->host_notify_domain,
+ client->addr);
+
+ return irq > 0 ? irq : -ENXIO;
+}
+
static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
@@ -914,6 +940,14 @@ static int i2c_device_probe(struct device *dev)
}
if (irq == -EPROBE_DEFER)
return irq;
+ /*
+ * ACPI and OF did not find any useful IRQ, try to see
+ * if Host Notify can be used.
+ */
+ if (irq < 0) {
+ dev_dbg(dev, "Using Host Notify IRQ\n");
+ irq = i2c_smbus_host_notify_to_irq(client);
+ }
if (irq < 0)
irq = 0;
@@ -921,7 +955,13 @@ static int i2c_device_probe(struct device *dev)
}
driver = to_i2c_driver(dev->driver);
- if (!driver->probe || !driver->id_table)
+
+ /*
+ * An I2C ID table is not mandatory, if and only if, a suitable Device
+ * Tree match table entry is supplied for the probing device.
+ */
+ if (!driver->id_table &&
+ !i2c_of_match_device(dev->driver->of_match_table, client))
return -ENODEV;
if (client->flags & I2C_CLIENT_WAKE) {
@@ -956,7 +996,18 @@ static int i2c_device_probe(struct device *dev)
if (status == -EPROBE_DEFER)
goto err_clear_wakeup_irq;
- status = driver->probe(client, i2c_match_id(driver->id_table, client));
+ /*
+ * When there are no more users of probe(),
+ * rename probe_new to probe.
+ */
+ if (driver->probe_new)
+ status = driver->probe_new(client);
+ else if (driver->probe)
+ status = driver->probe(client,
+ i2c_match_id(driver->id_table, client));
+ else
+ status = -EINVAL;
+
if (status)
goto err_detach_pm_domain;
@@ -1767,6 +1818,52 @@ struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node)
return adapter;
}
EXPORT_SYMBOL(of_get_i2c_adapter_by_node);
+
+static const struct of_device_id*
+i2c_of_match_device_sysfs(const struct of_device_id *matches,
+ struct i2c_client *client)
+{
+ const char *name;
+
+ for (; matches->compatible[0]; matches++) {
+ /*
+ * Adding devices through the i2c sysfs interface provides us
+ * a string to match which may be compatible with the device
+ * tree compatible strings, however with no actual of_node the
+ * of_match_device() will not match
+ */
+ if (sysfs_streq(client->name, matches->compatible))
+ return matches;
+
+ name = strchr(matches->compatible, ',');
+ if (!name)
+ name = matches->compatible;
+ else
+ name++;
+
+ if (sysfs_streq(client->name, name))
+ return matches;
+ }
+
+ return NULL;
+}
+
+const struct of_device_id
+*i2c_of_match_device(const struct of_device_id *matches,
+ struct i2c_client *client)
+{
+ const struct of_device_id *match;
+
+ if (!(client && matches))
+ return NULL;
+
+ match = of_match_device(matches, &client->dev);
+ if (match)
+ return match;
+
+ return i2c_of_match_device_sysfs(matches, client);
+}
+EXPORT_SYMBOL_GPL(i2c_of_match_device);
#else
static void of_i2c_register_devices(struct i2c_adapter *adap) { }
#endif /* CONFIG_OF */
@@ -1800,6 +1897,79 @@ static const struct i2c_lock_operations i2c_adapter_lock_ops = {
.unlock_bus = i2c_adapter_unlock_bus,
};
+static void i2c_host_notify_irq_teardown(struct i2c_adapter *adap)
+{
+ struct irq_domain *domain = adap->host_notify_domain;
+ irq_hw_number_t hwirq;
+
+ if (!domain)
+ return;
+
+ for (hwirq = 0 ; hwirq < I2C_ADDR_7BITS_COUNT ; hwirq++)
+ irq_dispose_mapping(irq_find_mapping(domain, hwirq));
+
+ irq_domain_remove(domain);
+ adap->host_notify_domain = NULL;
+}
+
+static int i2c_host_notify_irq_map(struct irq_domain *h,
+ unsigned int virq,
+ irq_hw_number_t hw_irq_num)
+{
+ irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops i2c_host_notify_irq_ops = {
+ .map = i2c_host_notify_irq_map,
+};
+
+static int i2c_setup_host_notify_irq_domain(struct i2c_adapter *adap)
+{
+ struct irq_domain *domain;
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_HOST_NOTIFY))
+ return 0;
+
+ domain = irq_domain_create_linear(adap->dev.fwnode,
+ I2C_ADDR_7BITS_COUNT,
+ &i2c_host_notify_irq_ops, adap);
+ if (!domain)
+ return -ENOMEM;
+
+ adap->host_notify_domain = domain;
+
+ return 0;
+}
+
+/**
+ * i2c_handle_smbus_host_notify - Forward a Host Notify event to the correct
+ * I2C client.
+ * @adap: the adapter
+ * @addr: the I2C address of the notifying device
+ * Context: can't sleep
+ *
+ * Helper function to be called from an I2C bus driver's interrupt
+ * handler. It will schedule the Host Notify IRQ.
+ */
+int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr)
+{
+ int irq;
+
+ if (!adap)
+ return -EINVAL;
+
+ irq = irq_find_mapping(adap->host_notify_domain, addr);
+ if (irq <= 0)
+ return -ENXIO;
+
+ generic_handle_irq(irq);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(i2c_handle_smbus_host_notify);
+
static int i2c_register_adapter(struct i2c_adapter *adap)
{
int res = -EINVAL;
@@ -1831,6 +2001,14 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
if (adap->timeout == 0)
adap->timeout = HZ;
+ /* register soft irqs for Host Notify */
+ res = i2c_setup_host_notify_irq_domain(adap);
+ if (res) {
+ pr_err("adapter '%s': can't create Host Notify IRQs (%d)\n",
+ adap->name, res);
+ goto out_list;
+ }
+
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
adap->dev.bus = &i2c_bus_type;
adap->dev.type = &i2c_adapter_type;
@@ -2068,6 +2246,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
pm_runtime_disable(&adap->dev);
+ i2c_host_notify_irq_teardown(adap);
+
/* wait until all references to the device are gone
*
* FIXME: This is old code and should ideally be replaced by an
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index b0d2679c60d1..f9271c713d20 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -241,108 +241,6 @@ int i2c_handle_smbus_alert(struct i2c_client *ara)
}
EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert);
-static void smbus_host_notify_work(struct work_struct *work)
-{
- struct alert_data alert;
- struct i2c_adapter *adapter;
- unsigned long flags;
- u16 payload;
- u8 addr;
- struct smbus_host_notify *data;
-
- data = container_of(work, struct smbus_host_notify, work);
-
- spin_lock_irqsave(&data->lock, flags);
- payload = data->payload;
- addr = data->addr;
- adapter = data->adapter;
-
- /* clear the pending bit and release the spinlock */
- data->pending = false;
- spin_unlock_irqrestore(&data->lock, flags);
-
- if (!adapter || !addr)
- return;
-
- alert.type = I2C_PROTOCOL_SMBUS_HOST_NOTIFY;
- alert.addr = addr;
- alert.data = payload;
-
- device_for_each_child(&adapter->dev, &alert, smbus_do_alert);
-}
-
-/**
- * i2c_setup_smbus_host_notify - Allocate a new smbus_host_notify for the given
- * I2C adapter.
- * @adapter: the adapter we want to associate a Host Notify function
- *
- * Returns a struct smbus_host_notify pointer on success, and NULL on failure.
- * The resulting smbus_host_notify must not be freed afterwards, it is a
- * managed resource already.
- */
-struct smbus_host_notify *i2c_setup_smbus_host_notify(struct i2c_adapter *adap)
-{
- struct smbus_host_notify *host_notify;
-
- host_notify = devm_kzalloc(&adap->dev, sizeof(struct smbus_host_notify),
- GFP_KERNEL);
- if (!host_notify)
- return NULL;
-
- host_notify->adapter = adap;
-
- spin_lock_init(&host_notify->lock);
- INIT_WORK(&host_notify->work, smbus_host_notify_work);
-
- return host_notify;
-}
-EXPORT_SYMBOL_GPL(i2c_setup_smbus_host_notify);
-
-/**
- * i2c_handle_smbus_host_notify - Forward a Host Notify event to the correct
- * I2C client.
- * @host_notify: the struct host_notify attached to the relevant adapter
- * @addr: the I2C address of the notifying device
- * @data: the payload of the notification
- * Context: can't sleep
- *
- * Helper function to be called from an I2C bus driver's interrupt
- * handler. It will schedule the Host Notify work, in turn calling the
- * corresponding I2C device driver's alert function.
- *
- * host_notify should be a valid pointer previously returned by
- * i2c_setup_smbus_host_notify().
- */
-int i2c_handle_smbus_host_notify(struct smbus_host_notify *host_notify,
- unsigned short addr, unsigned int data)
-{
- unsigned long flags;
- struct i2c_adapter *adapter;
-
- if (!host_notify || !host_notify->adapter)
- return -EINVAL;
-
- adapter = host_notify->adapter;
-
- spin_lock_irqsave(&host_notify->lock, flags);
-
- if (host_notify->pending) {
- spin_unlock_irqrestore(&host_notify->lock, flags);
- dev_warn(&adapter->dev, "Host Notify already scheduled.\n");
- return -EBUSY;
- }
-
- host_notify->payload = data;
- host_notify->addr = addr;
-
- /* Mark that there is a pending notification and release the lock */
- host_notify->pending = true;
- spin_unlock_irqrestore(&host_notify->lock, flags);
-
- return schedule_work(&host_notify->work);
-}
-EXPORT_SYMBOL_GPL(i2c_handle_smbus_host_notify);
-
module_i2c_driver(smbalert_driver);
MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 96de9ce5669b..10b3d17ae3ea 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -82,4 +82,15 @@ config I2C_DEMUX_PINCTRL
demultiplexer that uses the pinctrl subsystem. This is useful if you
want to change the I2C master at run-time depending on features.
+config I2C_MUX_MLXCPLD
+ tristate "Mellanox CPLD based I2C multiplexer"
+ help
+ If you say yes to this option, support will be included for a
+ CPLD based I2C multiplexer. This driver provides access to
+ I2C busses connected through a MUX, which is controlled
+ by a CPLD register.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-mux-mlxcpld.
+
endmenu
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile
index 7c267c29b191..9948fa45037f 100644
--- a/drivers/i2c/muxes/Makefile
+++ b/drivers/i2c/muxes/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o
obj-$(CONFIG_I2C_DEMUX_PINCTRL) += i2c-demux-pinctrl.o
obj-$(CONFIG_I2C_MUX_GPIO) += i2c-mux-gpio.o
+obj-$(CONFIG_I2C_MUX_MLXCPLD) += i2c-mux-mlxcpld.o
obj-$(CONFIG_I2C_MUX_PCA9541) += i2c-mux-pca9541.o
obj-$(CONFIG_I2C_MUX_PCA954x) += i2c-mux-pca954x.o
obj-$(CONFIG_I2C_MUX_PINCTRL) += i2c-mux-pinctrl.o
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index e5cf26eefa97..655684d621a4 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -21,6 +21,8 @@
struct gpiomux {
struct i2c_mux_gpio_platform_data data;
unsigned gpio_base;
+ struct gpio_desc **gpios;
+ int *values;
};
static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
@@ -28,8 +30,10 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
int i;
for (i = 0; i < mux->data.n_gpios; i++)
- gpio_set_value_cansleep(mux->gpio_base + mux->data.gpios[i],
- val & (1 << i));
+ mux->values[i] = (val >> i) & 1;
+
+ gpiod_set_array_value_cansleep(mux->data.n_gpios,
+ mux->gpios, mux->values);
}
static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
@@ -176,12 +180,16 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
if (!parent)
return -EPROBE_DEFER;
- muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 0, 0,
+ muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values,
+ mux->data.n_gpios * sizeof(*mux->gpios) +
+ mux->data.n_gpios * sizeof(*mux->values), 0,
i2c_mux_gpio_select, NULL);
if (!muxc) {
ret = -ENOMEM;
goto alloc_failed;
}
+ mux->gpios = muxc->priv;
+ mux->values = (int *)(mux->gpios + mux->data.n_gpios);
muxc->priv = mux;
platform_set_drvdata(pdev, muxc);
@@ -219,10 +227,12 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
goto err_request_gpio;
}
+ gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]);
+ mux->gpios[i] = gpio_desc;
+
if (!muxc->mux_locked)
continue;
- gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]);
gpio_dev = &gpio_desc->gdev->dev;
muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
}
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
new file mode 100644
index 000000000000..3ab654bbfab5
--- /dev/null
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
@@ -0,0 +1,220 @@
+/*
+ * drivers/i2c/muxes/i2c-mux-mlxcpld.c
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Michael Shych <michaels@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/i2c/mlxcpld.h>
+
+#define CPLD_MUX_MAX_NCHANS 8
+
+/* mlxcpld_mux - mux control structure:
+ * @last_chan - last register value
+ * @client - I2C device client
+ */
+struct mlxcpld_mux {
+ u8 last_chan;
+ struct i2c_client *client;
+};
+
+/* MUX logic description.
+ * Driver can support different mux control logic, according to CPLD
+ * implementation.
+ *
+ * Connectivity schema.
+ *
+ * i2c-mlxcpld Digital Analog
+ * driver
+ * *--------* * -> mux1 (virt bus2) -> mux -> |
+ * | I2CLPC | i2c physical * -> mux2 (virt bus3) -> mux -> |
+ * | bridge | bus 1 *---------* |
+ * | logic |---------------------> * mux reg * |
+ * | in CPLD| *---------* |
+ * *--------* i2c-mux-mlxpcld ^ * -> muxn (virt busn) -> mux -> |
+ * | driver | |
+ * | *---------------* | Devices
+ * | * CPLD (i2c bus)* select |
+ * | * registers for *--------*
+ * | * mux selection * deselect
+ * | *---------------*
+ * | |
+ * <--------> <----------->
+ * i2c cntrl Board cntrl reg
+ * reg space space (mux select,
+ * IO, LED, WD, info)
+ *
+ */
+
+static const struct i2c_device_id mlxcpld_mux_id[] = {
+ { "mlxcpld_mux_module", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mlxcpld_mux_id);
+
+/* Write to mux register. Don't use i2c_transfer() and i2c_smbus_xfer()
+ * for this as they will try to lock adapter a second time.
+ */
+static int mlxcpld_mux_reg_write(struct i2c_adapter *adap,
+ struct i2c_client *client, u8 val)
+{
+ struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev);
+
+ if (adap->algo->master_xfer) {
+ struct i2c_msg msg;
+ u8 msgbuf[] = {pdata->sel_reg_addr, val};
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ msg.buf = msgbuf;
+ return __i2c_transfer(adap, &msg, 1);
+ } else if (adap->algo->smbus_xfer) {
+ union i2c_smbus_data data;
+
+ data.byte = val;
+ return adap->algo->smbus_xfer(adap, client->addr,
+ client->flags, I2C_SMBUS_WRITE,
+ pdata->sel_reg_addr,
+ I2C_SMBUS_BYTE_DATA, &data);
+ } else
+ return -ENODEV;
+}
+
+static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
+{
+ struct mlxcpld_mux *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+ u8 regval = chan + 1;
+ int err = 0;
+
+ /* Only select the channel if its different from the last channel */
+ if (data->last_chan != regval) {
+ err = mlxcpld_mux_reg_write(muxc->parent, client, regval);
+ if (err)
+ data->last_chan = 0;
+ else
+ data->last_chan = regval;
+ }
+
+ return err;
+}
+
+static int mlxcpld_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+ struct mlxcpld_mux *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+
+ /* Deselect active channel */
+ data->last_chan = 0;
+
+ return mlxcpld_mux_reg_write(muxc->parent, client, data->last_chan);
+}
+
+/* Probe/reomove functions */
+static int mlxcpld_mux_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+ struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev);
+ struct i2c_mux_core *muxc;
+ int num, force;
+ struct mlxcpld_mux *data;
+ int err;
+
+ if (!pdata)
+ return -EINVAL;
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ return -ENODEV;
+
+ muxc = i2c_mux_alloc(adap, &client->dev, CPLD_MUX_MAX_NCHANS,
+ sizeof(*data), 0, mlxcpld_mux_select_chan,
+ mlxcpld_mux_deselect);
+ if (!muxc)
+ return -ENOMEM;
+
+ data = i2c_mux_priv(muxc);
+ i2c_set_clientdata(client, muxc);
+ data->client = client;
+ data->last_chan = 0; /* force the first selection */
+
+ /* Create an adapter for each channel. */
+ for (num = 0; num < CPLD_MUX_MAX_NCHANS; num++) {
+ if (num >= pdata->num_adaps)
+ /* discard unconfigured channels */
+ break;
+
+ force = pdata->adap_ids[num];
+
+ err = i2c_mux_add_adapter(muxc, force, num, 0);
+ if (err)
+ goto virt_reg_failed;
+ }
+
+ return 0;
+
+virt_reg_failed:
+ i2c_mux_del_adapters(muxc);
+ return err;
+}
+
+static int mlxcpld_mux_remove(struct i2c_client *client)
+{
+ struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+
+ i2c_mux_del_adapters(muxc);
+ return 0;
+}
+
+static struct i2c_driver mlxcpld_mux_driver = {
+ .driver = {
+ .name = "mlxcpld-mux",
+ },
+ .probe = mlxcpld_mux_probe,
+ .remove = mlxcpld_mux_remove,
+ .id_table = mlxcpld_mux_id,
+};
+
+module_i2c_driver(mlxcpld_mux_driver);
+
+MODULE_AUTHOR("Michael Shych (michaels@mellanox.com)");
+MODULE_DESCRIPTION("Mellanox I2C-CPLD-MUX driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:i2c-mux-mlxcpld");
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 8bc3d36d2837..9a348ee4dc14 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -35,6 +35,7 @@
* warranty of any kind, whether express or implied.
*/
+#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
@@ -120,6 +121,21 @@ static const struct i2c_device_id pca954x_id[] = {
};
MODULE_DEVICE_TABLE(i2c, pca954x_id);
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id pca954x_acpi_ids[] = {
+ { .id = "PCA9540", .driver_data = pca_9540 },
+ { .id = "PCA9542", .driver_data = pca_9540 },
+ { .id = "PCA9543", .driver_data = pca_9543 },
+ { .id = "PCA9544", .driver_data = pca_9544 },
+ { .id = "PCA9545", .driver_data = pca_9545 },
+ { .id = "PCA9546", .driver_data = pca_9545 },
+ { .id = "PCA9547", .driver_data = pca_9547 },
+ { .id = "PCA9548", .driver_data = pca_9548 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, pca954x_acpi_ids);
+#endif
+
#ifdef CONFIG_OF
static const struct of_device_id pca954x_of_match[] = {
{ .compatible = "nxp,pca9540", .data = &chips[pca_9540] },
@@ -245,8 +261,17 @@ static int pca954x_probe(struct i2c_client *client,
match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
if (match)
data->chip = of_device_get_match_data(&client->dev);
- else
+ else if (id)
data->chip = &chips[id->driver_data];
+ else {
+ const struct acpi_device_id *acpi_id;
+
+ acpi_id = acpi_match_device(ACPI_PTR(pca954x_acpi_ids),
+ &client->dev);
+ if (!acpi_id)
+ return -ENODEV;
+ data->chip = &chips[acpi_id->driver_data];
+ }
data->last_chan = 0; /* force the first selection */
@@ -321,6 +346,7 @@ static struct i2c_driver pca954x_driver = {
.name = "pca954x",
.pm = &pca954x_pm,
.of_match_table = of_match_ptr(pca954x_of_match),
+ .acpi_match_table = ACPI_PTR(pca954x_acpi_ids),
},
.probe = pca954x_probe,
.remove = pca954x_remove,
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index fb3fb89640e5..670917387eda 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -73,6 +73,7 @@ source "drivers/infiniband/hw/mlx4/Kconfig"
source "drivers/infiniband/hw/mlx5/Kconfig"
source "drivers/infiniband/hw/nes/Kconfig"
source "drivers/infiniband/hw/ocrdma/Kconfig"
+source "drivers/infiniband/hw/vmw_pvrdma/Kconfig"
source "drivers/infiniband/hw/usnic/Kconfig"
source "drivers/infiniband/hw/hns/Kconfig"
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index 4fa524dfb6cf..11dacd97a667 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -156,7 +156,6 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
/* Create new device info */
port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL);
if (!port_priv) {
- dev_err(&device->dev, "No memory for ib_agent_port_private\n");
ret = -ENOMEM;
goto error1;
}
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 1a2984c28b95..ae04826e82fc 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -770,12 +770,8 @@ static int _gid_table_setup_one(struct ib_device *ib_dev)
int err = 0;
table = kcalloc(ib_dev->phys_port_cnt, sizeof(*table), GFP_KERNEL);
-
- if (!table) {
- pr_warn("failed to allocate ib gid cache for %s\n",
- ib_dev->name);
+ if (!table)
return -ENOMEM;
- }
for (port = 0; port < ib_dev->phys_port_cnt; port++) {
u8 rdma_port = port + rdma_start_port(ib_dev);
@@ -1170,14 +1166,13 @@ int ib_cache_setup_one(struct ib_device *device)
GFP_KERNEL);
if (!device->cache.pkey_cache ||
!device->cache.lmc_cache) {
- pr_warn("Couldn't allocate cache for %s\n", device->name);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto free;
}
err = gid_table_setup_one(device);
if (err)
- /* Allocated memory will be cleaned in the release function */
- return err;
+ goto free;
for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
ib_cache_update(device, p + rdma_start_port(device));
@@ -1192,6 +1187,9 @@ int ib_cache_setup_one(struct ib_device *device)
err:
gid_table_cleanup_one(device);
+free:
+ kfree(device->cache.pkey_cache);
+ kfree(device->cache.lmc_cache);
return err;
}
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 71c7c4c328ef..cf1edfa1cbac 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -57,6 +57,54 @@ MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("InfiniBand CM");
MODULE_LICENSE("Dual BSD/GPL");
+static const char * const ibcm_rej_reason_strs[] = {
+ [IB_CM_REJ_NO_QP] = "no QP",
+ [IB_CM_REJ_NO_EEC] = "no EEC",
+ [IB_CM_REJ_NO_RESOURCES] = "no resources",
+ [IB_CM_REJ_TIMEOUT] = "timeout",
+ [IB_CM_REJ_UNSUPPORTED] = "unsupported",
+ [IB_CM_REJ_INVALID_COMM_ID] = "invalid comm ID",
+ [IB_CM_REJ_INVALID_COMM_INSTANCE] = "invalid comm instance",
+ [IB_CM_REJ_INVALID_SERVICE_ID] = "invalid service ID",
+ [IB_CM_REJ_INVALID_TRANSPORT_TYPE] = "invalid transport type",
+ [IB_CM_REJ_STALE_CONN] = "stale conn",
+ [IB_CM_REJ_RDC_NOT_EXIST] = "RDC not exist",
+ [IB_CM_REJ_INVALID_GID] = "invalid GID",
+ [IB_CM_REJ_INVALID_LID] = "invalid LID",
+ [IB_CM_REJ_INVALID_SL] = "invalid SL",
+ [IB_CM_REJ_INVALID_TRAFFIC_CLASS] = "invalid traffic class",
+ [IB_CM_REJ_INVALID_HOP_LIMIT] = "invalid hop limit",
+ [IB_CM_REJ_INVALID_PACKET_RATE] = "invalid packet rate",
+ [IB_CM_REJ_INVALID_ALT_GID] = "invalid alt GID",
+ [IB_CM_REJ_INVALID_ALT_LID] = "invalid alt LID",
+ [IB_CM_REJ_INVALID_ALT_SL] = "invalid alt SL",
+ [IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS] = "invalid alt traffic class",
+ [IB_CM_REJ_INVALID_ALT_HOP_LIMIT] = "invalid alt hop limit",
+ [IB_CM_REJ_INVALID_ALT_PACKET_RATE] = "invalid alt packet rate",
+ [IB_CM_REJ_PORT_CM_REDIRECT] = "port CM redirect",
+ [IB_CM_REJ_PORT_REDIRECT] = "port redirect",
+ [IB_CM_REJ_INVALID_MTU] = "invalid MTU",
+ [IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES] = "insufficient resp resources",
+ [IB_CM_REJ_CONSUMER_DEFINED] = "consumer defined",
+ [IB_CM_REJ_INVALID_RNR_RETRY] = "invalid RNR retry",
+ [IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID] = "duplicate local comm ID",
+ [IB_CM_REJ_INVALID_CLASS_VERSION] = "invalid class version",
+ [IB_CM_REJ_INVALID_FLOW_LABEL] = "invalid flow label",
+ [IB_CM_REJ_INVALID_ALT_FLOW_LABEL] = "invalid alt flow label",
+};
+
+const char *__attribute_const__ ibcm_reject_msg(int reason)
+{
+ size_t index = reason;
+
+ if (index < ARRAY_SIZE(ibcm_rej_reason_strs) &&
+ ibcm_rej_reason_strs[index])
+ return ibcm_rej_reason_strs[index];
+ else
+ return "unrecognized reason";
+}
+EXPORT_SYMBOL(ibcm_reject_msg);
+
static void cm_add_one(struct ib_device *device);
static void cm_remove_one(struct ib_device *device, void *client_data);
@@ -1582,6 +1630,7 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
struct cm_id_private *listen_cm_id_priv, *cur_cm_id_priv;
struct cm_timewait_info *timewait_info;
struct cm_req_msg *req_msg;
+ struct ib_cm_id *cm_id;
req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1603,10 +1652,18 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
if (timewait_info) {
cm_cleanup_timewait(cm_id_priv->timewait_info);
+ cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
+ timewait_info->work.remote_id);
+
spin_unlock_irq(&cm.lock);
cm_issue_rej(work->port, work->mad_recv_wc,
IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
NULL, 0);
+ if (cur_cm_id_priv) {
+ cm_id = &cur_cm_id_priv->id;
+ ib_send_cm_dreq(cm_id, NULL, 0);
+ cm_deref_id(cur_cm_id_priv);
+ }
return NULL;
}
@@ -1984,6 +2041,9 @@ static int cm_rep_handler(struct cm_work *work)
struct cm_id_private *cm_id_priv;
struct cm_rep_msg *rep_msg;
int ret;
+ struct cm_id_private *cur_cm_id_priv;
+ struct ib_cm_id *cm_id;
+ struct cm_timewait_info *timewait_info;
rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id, 0);
@@ -2018,16 +2078,26 @@ static int cm_rep_handler(struct cm_work *work)
goto error;
}
/* Check for a stale connection. */
- if (cm_insert_remote_qpn(cm_id_priv->timewait_info)) {
+ timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
+ if (timewait_info) {
rb_erase(&cm_id_priv->timewait_info->remote_id_node,
&cm.remote_id_table);
cm_id_priv->timewait_info->inserted_remote_id = 0;
+ cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
+ timewait_info->work.remote_id);
+
spin_unlock(&cm.lock);
spin_unlock_irq(&cm_id_priv->lock);
cm_issue_rej(work->port, work->mad_recv_wc,
IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REP,
NULL, 0);
ret = -EINVAL;
+ if (cur_cm_id_priv) {
+ cm_id = &cur_cm_id_priv->id;
+ ib_send_cm_dreq(cm_id, NULL, 0);
+ cm_deref_id(cur_cm_id_priv);
+ }
+
goto error;
}
spin_unlock(&cm.lock);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 22fcf284dd8b..e7dcfac877ca 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -101,6 +101,49 @@ const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event)
}
EXPORT_SYMBOL(rdma_event_msg);
+const char *__attribute_const__ rdma_reject_msg(struct rdma_cm_id *id,
+ int reason)
+{
+ if (rdma_ib_or_roce(id->device, id->port_num))
+ return ibcm_reject_msg(reason);
+
+ if (rdma_protocol_iwarp(id->device, id->port_num))
+ return iwcm_reject_msg(reason);
+
+ WARN_ON_ONCE(1);
+ return "unrecognized transport";
+}
+EXPORT_SYMBOL(rdma_reject_msg);
+
+bool rdma_is_consumer_reject(struct rdma_cm_id *id, int reason)
+{
+ if (rdma_ib_or_roce(id->device, id->port_num))
+ return reason == IB_CM_REJ_CONSUMER_DEFINED;
+
+ if (rdma_protocol_iwarp(id->device, id->port_num))
+ return reason == -ECONNREFUSED;
+
+ WARN_ON_ONCE(1);
+ return false;
+}
+EXPORT_SYMBOL(rdma_is_consumer_reject);
+
+const void *rdma_consumer_reject_data(struct rdma_cm_id *id,
+ struct rdma_cm_event *ev, u8 *data_len)
+{
+ const void *p;
+
+ if (rdma_is_consumer_reject(id, ev->status)) {
+ *data_len = ev->param.conn.private_data_len;
+ p = ev->param.conn.private_data;
+ } else {
+ *data_len = 0;
+ p = NULL;
+ }
+ return p;
+}
+EXPORT_SYMBOL(rdma_consumer_reject_data);
+
static void cma_add_one(struct ib_device *device);
static void cma_remove_one(struct ib_device *device, void *client_data);
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 0c0bea091de8..d29372624f3a 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -72,9 +72,6 @@ void ib_device_unregister_sysfs(struct ib_device *device);
void ib_cache_setup(void);
void ib_cache_cleanup(void);
-int ib_resolve_eth_dmac(struct ib_qp *qp,
- struct ib_qp_attr *qp_attr, int *qp_attr_mask);
-
typedef void (*roce_netdev_callback)(struct ib_device *device, u8 port,
struct net_device *idev, void *cookie);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 760ef603a468..571974cd3919 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -254,11 +254,8 @@ static int add_client_context(struct ib_device *device, struct ib_client *client
unsigned long flags;
context = kmalloc(sizeof *context, GFP_KERNEL);
- if (!context) {
- pr_warn("Couldn't allocate client context for %s/%s\n",
- device->name, client->name);
+ if (!context)
return -ENOMEM;
- }
context->client = client;
context->data = NULL;
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index cdbb1f1a6d97..cdfad5f26212 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -247,7 +247,6 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket,
GFP_KERNEL);
if (!pool->cache_bucket) {
- pr_warn(PFX "Failed to allocate cache in pool\n");
ret = -ENOMEM;
goto out_free_pool;
}
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 5495e22839a7..31661b5c1743 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -59,6 +59,27 @@ MODULE_AUTHOR("Tom Tucker");
MODULE_DESCRIPTION("iWARP CM");
MODULE_LICENSE("Dual BSD/GPL");
+static const char * const iwcm_rej_reason_strs[] = {
+ [ECONNRESET] = "reset by remote host",
+ [ECONNREFUSED] = "refused by remote application",
+ [ETIMEDOUT] = "setup timeout",
+};
+
+const char *__attribute_const__ iwcm_reject_msg(int reason)
+{
+ size_t index;
+
+ /* iWARP uses negative errnos */
+ index = -reason;
+
+ if (index < ARRAY_SIZE(iwcm_rej_reason_strs) &&
+ iwcm_rej_reason_strs[index])
+ return iwcm_rej_reason_strs[index];
+ else
+ return "unrecognized reason";
+}
+EXPORT_SYMBOL(iwcm_reject_msg);
+
static struct ibnl_client_cbs iwcm_nl_cb_table[] = {
[RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb},
[RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb},
diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c
index 1c41b95cefec..a0e7c16d8bd8 100644
--- a/drivers/infiniband/core/iwpm_msg.c
+++ b/drivers/infiniband/core/iwpm_msg.c
@@ -604,7 +604,6 @@ int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
}
rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
if (!rem_info) {
- pr_err("%s: Unable to allocate a remote info\n", __func__);
ret = -ENOMEM;
return ret;
}
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c
index ade71e7f0131..3ef51a96bbf1 100644
--- a/drivers/infiniband/core/iwpm_util.c
+++ b/drivers/infiniband/core/iwpm_util.c
@@ -62,7 +62,6 @@ int iwpm_init(u8 nl_client)
sizeof(struct hlist_head), GFP_KERNEL);
if (!iwpm_hash_bucket) {
ret = -ENOMEM;
- pr_err("%s Unable to create mapinfo hash table\n", __func__);
goto init_exit;
}
iwpm_reminfo_bucket = kzalloc(IWPM_REMINFO_HASH_SIZE *
@@ -70,7 +69,6 @@ int iwpm_init(u8 nl_client)
if (!iwpm_reminfo_bucket) {
kfree(iwpm_hash_bucket);
ret = -ENOMEM;
- pr_err("%s Unable to create reminfo hash table\n", __func__);
goto init_exit;
}
}
@@ -128,10 +126,9 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr,
if (!iwpm_valid_client(nl_client))
return ret;
map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL);
- if (!map_info) {
- pr_err("%s: Unable to allocate a mapping info\n", __func__);
+ if (!map_info)
return -ENOMEM;
- }
+
memcpy(&map_info->local_sockaddr, local_sockaddr,
sizeof(struct sockaddr_storage));
memcpy(&map_info->mapped_sockaddr, mapped_sockaddr,
@@ -309,10 +306,9 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
unsigned long flags;
nlmsg_request = kzalloc(sizeof(struct iwpm_nlmsg_request), gfp);
- if (!nlmsg_request) {
- pr_err("%s Unable to allocate a nlmsg_request\n", __func__);
+ if (!nlmsg_request)
return NULL;
- }
+
spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
list_add_tail(&nlmsg_request->inprocess_list, &iwpm_nlmsg_req_list);
spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 40cbd6bdb73b..a009f7132c73 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -769,7 +769,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
* If we are at the start of the LID routed part, don't update the
* hop_ptr or hop_cnt. See section 14.2.2, Vol 1 IB spec.
*/
- if (opa && smp->class_version == OPA_SMP_CLASS_VERSION) {
+ if (opa && smp->class_version == OPA_SM_CLASS_VERSION) {
u32 opa_drslid;
if ((opa_get_smp_direction(opa_smp)
@@ -816,7 +816,6 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
local = kmalloc(sizeof *local, GFP_ATOMIC);
if (!local) {
ret = -ENOMEM;
- dev_err(&device->dev, "No memory for ib_mad_local_private\n");
goto out;
}
local->mad_priv = NULL;
@@ -824,7 +823,6 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
mad_priv = alloc_mad_private(mad_size, GFP_ATOMIC);
if (!mad_priv) {
ret = -ENOMEM;
- dev_err(&device->dev, "No memory for local response MAD\n");
kfree(local);
goto out;
}
@@ -947,9 +945,6 @@ static int alloc_send_rmpp_list(struct ib_mad_send_wr_private *send_wr,
for (left = send_buf->data_len + pad; left > 0; left -= seg_size) {
seg = kmalloc(sizeof (*seg) + seg_size, gfp_mask);
if (!seg) {
- dev_err(&send_buf->mad_agent->device->dev,
- "alloc_send_rmpp_segs: RMPP mem alloc failed for len %zd, gfp %#x\n",
- sizeof (*seg) + seg_size, gfp_mask);
free_send_rmpp_list(send_wr);
return -ENOMEM;
}
@@ -1362,12 +1357,7 @@ static int allocate_method_table(struct ib_mad_mgmt_method_table **method)
{
/* Allocate management method table */
*method = kzalloc(sizeof **method, GFP_ATOMIC);
- if (!*method) {
- pr_err("No memory for ib_mad_mgmt_method_table\n");
- return -ENOMEM;
- }
-
- return 0;
+ return (*method) ? 0 : (-ENOMEM);
}
/*
@@ -1458,8 +1448,6 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
/* Allocate management class table for "new" class version */
*class = kzalloc(sizeof **class, GFP_ATOMIC);
if (!*class) {
- dev_err(&agent_priv->agent.device->dev,
- "No memory for ib_mad_mgmt_class_table\n");
ret = -ENOMEM;
goto error1;
}
@@ -1524,22 +1512,16 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
if (!*vendor_table) {
/* Allocate mgmt vendor class table for "new" class version */
vendor = kzalloc(sizeof *vendor, GFP_ATOMIC);
- if (!vendor) {
- dev_err(&agent_priv->agent.device->dev,
- "No memory for ib_mad_mgmt_vendor_class_table\n");
+ if (!vendor)
goto error1;
- }
*vendor_table = vendor;
}
if (!(*vendor_table)->vendor_class[vclass]) {
/* Allocate table for this management vendor class */
vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC);
- if (!vendor_class) {
- dev_err(&agent_priv->agent.device->dev,
- "No memory for ib_mad_mgmt_vendor_class\n");
+ if (!vendor_class)
goto error2;
- }
(*vendor_table)->vendor_class[vclass] = vendor_class;
}
@@ -1746,7 +1728,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv,
if (!class)
goto out;
if (convert_mgmt_class(mad_hdr->mgmt_class) >=
- IB_MGMT_MAX_METHODS)
+ ARRAY_SIZE(class->method_table))
goto out;
method = class->method_table[convert_mgmt_class(
mad_hdr->mgmt_class)];
@@ -2167,7 +2149,7 @@ handle_smi(struct ib_mad_port_private *port_priv,
struct ib_mad_hdr *mad_hdr = (struct ib_mad_hdr *)recv->mad;
if (opa && mad_hdr->base_version == OPA_MGMT_BASE_VERSION &&
- mad_hdr->class_version == OPA_SMI_CLASS_VERSION)
+ mad_hdr->class_version == OPA_SM_CLASS_VERSION)
return handle_opa_smi(port_priv, qp_info, wc, port_num, recv,
response);
@@ -2238,11 +2220,8 @@ static void ib_mad_recv_done(struct ib_cq *cq, struct ib_wc *wc)
mad_size = recv->mad_size;
response = alloc_mad_private(mad_size, GFP_KERNEL);
- if (!response) {
- dev_err(&port_priv->device->dev,
- "%s: no memory for response buffer\n", __func__);
+ if (!response)
goto out;
- }
if (rdma_cap_ib_switch(port_priv->device))
port_num = wc->port_num;
@@ -2869,8 +2848,6 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
mad_priv = alloc_mad_private(port_mad_size(qp_info->port_priv),
GFP_ATOMIC);
if (!mad_priv) {
- dev_err(&qp_info->port_priv->device->dev,
- "No memory for receive buffer\n");
ret = -ENOMEM;
break;
}
@@ -2961,11 +2938,8 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
u16 pkey_index;
attr = kmalloc(sizeof *attr, GFP_KERNEL);
- if (!attr) {
- dev_err(&port_priv->device->dev,
- "Couldn't kmalloc ib_qp_attr\n");
+ if (!attr)
return -ENOMEM;
- }
ret = ib_find_pkey(port_priv->device, port_priv->port_num,
IB_DEFAULT_PKEY_FULL, &pkey_index);
@@ -3135,10 +3109,8 @@ static int ib_mad_port_open(struct ib_device *device,
/* Create new device info */
port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL);
- if (!port_priv) {
- dev_err(&device->dev, "No memory for ib_mad_port_private\n");
+ if (!port_priv)
return -ENOMEM;
- }
port_priv->device = device;
port_priv->port_num = port_num;
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
index e51b739f6ea3..322cb67b07a9 100644
--- a/drivers/infiniband/core/multicast.c
+++ b/drivers/infiniband/core/multicast.c
@@ -518,8 +518,11 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
process_join_error(group, status);
else {
int mgids_changed, is_mgid0;
- ib_find_pkey(group->port->dev->device, group->port->port_num,
- be16_to_cpu(rec->pkey), &pkey_index);
+
+ if (ib_find_pkey(group->port->dev->device,
+ group->port->port_num, be16_to_cpu(rec->pkey),
+ &pkey_index))
+ pkey_index = MCAST_INVALID_PKEY_INDEX;
spin_lock_irq(&group->port->lock);
if (group->state == MCAST_BUSY &&
diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
index 3a64a0881882..0621f4455732 100644
--- a/drivers/infiniband/core/roce_gid_mgmt.c
+++ b/drivers/infiniband/core/roce_gid_mgmt.c
@@ -304,10 +304,9 @@ static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
for_ifa(in_dev) {
struct sin_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry) {
- pr_warn("roce_gid_mgmt: couldn't allocate entry for IPv4 update\n");
+ if (!entry)
continue;
- }
+
entry->ip.sin_family = AF_INET;
entry->ip.sin_addr.s_addr = ifa->ifa_address;
list_add_tail(&entry->list, &sin_list);
@@ -348,10 +347,8 @@ static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
struct sin6_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry) {
- pr_warn("roce_gid_mgmt: couldn't allocate entry for IPv6 update\n");
+ if (!entry)
continue;
- }
entry->sin6.sin6_family = AF_INET6;
entry->sin6.sin6_addr = ifp->addr;
@@ -447,10 +444,8 @@ static int netdev_upper_walk(struct net_device *upper, void *data)
struct upper_list *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
struct list_head *upper_list = data;
- if (!entry) {
- pr_info("roce_gid_mgmt: couldn't allocate entry to delete ndev\n");
+ if (!entry)
return 0;
- }
list_add_tail(&entry->list, upper_list);
dev_hold(upper);
@@ -559,10 +554,8 @@ static int netdevice_queue_work(struct netdev_event_work_cmd *cmds,
struct netdev_event_work *ndev_work =
kmalloc(sizeof(*ndev_work), GFP_KERNEL);
- if (!ndev_work) {
- pr_warn("roce_gid_mgmt: can't allocate work for netdevice_event\n");
+ if (!ndev_work)
return NOTIFY_DONE;
- }
memcpy(ndev_work->cmds, cmds, sizeof(ndev_work->cmds));
for (i = 0; i < ARRAY_SIZE(ndev_work->cmds) && ndev_work->cmds[i].cb; i++) {
@@ -696,10 +689,8 @@ static int addr_event(struct notifier_block *this, unsigned long event,
}
work = kmalloc(sizeof(*work), GFP_ATOMIC);
- if (!work) {
- pr_warn("roce_gid_mgmt: Couldn't allocate work for addr_event\n");
+ if (!work)
return NOTIFY_DONE;
- }
INIT_WORK(&work->work, update_gid_event_work_handler);
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 7713ef089c3c..579f9a7f6283 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -1104,8 +1104,11 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,
struct ib_ucm_cmd_hdr hdr;
ssize_t result;
- if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+ if (!ib_safe_file_access(filp)) {
+ pr_err_once("ucm_write: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n",
+ task_tgid_vnr(current), current->comm);
return -EACCES;
+ }
if (len < sizeof(hdr))
return -EINVAL;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 9520154f1d7c..e12f8faf8c23 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1584,8 +1584,11 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf,
struct rdma_ucm_cmd_hdr hdr;
ssize_t ret;
- if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+ if (!ib_safe_file_access(filp)) {
+ pr_err_once("ucma_write: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n",
+ task_tgid_vnr(current), current->comm);
return -EACCES;
+ }
if (len < sizeof(hdr))
return -EINVAL;
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 84b4eff90395..1e62a5f0cb28 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -51,7 +51,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
if (umem->nmap > 0)
ib_dma_unmap_sg(dev, umem->sg_head.sgl,
- umem->nmap,
+ umem->npages,
DMA_BIDIRECTIONAL);
for_each_sg(umem->sg_head.sgl, sg, umem->npages, i) {
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index df26a741cda6..455034ac994e 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -289,5 +289,6 @@ IB_UVERBS_DECLARE_EX_CMD(modify_wq);
IB_UVERBS_DECLARE_EX_CMD(destroy_wq);
IB_UVERBS_DECLARE_EX_CMD(create_rwq_ind_table);
IB_UVERBS_DECLARE_EX_CMD(destroy_rwq_ind_table);
+IB_UVERBS_DECLARE_EX_CMD(modify_qp);
#endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index cb3f515a2285..09b649159e6c 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -2328,94 +2328,88 @@ static int modify_qp_mask(enum ib_qp_type qp_type, int mask)
}
}
-ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
- struct ib_device *ib_dev,
- const char __user *buf, int in_len,
- int out_len)
+static int modify_qp(struct ib_uverbs_file *file,
+ struct ib_uverbs_ex_modify_qp *cmd, struct ib_udata *udata)
{
- struct ib_uverbs_modify_qp cmd;
- struct ib_udata udata;
- struct ib_qp *qp;
- struct ib_qp_attr *attr;
- int ret;
-
- if (copy_from_user(&cmd, buf, sizeof cmd))
- return -EFAULT;
-
- INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
- out_len);
+ struct ib_qp_attr *attr;
+ struct ib_qp *qp;
+ int ret;
attr = kmalloc(sizeof *attr, GFP_KERNEL);
if (!attr)
return -ENOMEM;
- qp = idr_read_qp(cmd.qp_handle, file->ucontext);
+ qp = idr_read_qp(cmd->base.qp_handle, file->ucontext);
if (!qp) {
ret = -EINVAL;
goto out;
}
- attr->qp_state = cmd.qp_state;
- attr->cur_qp_state = cmd.cur_qp_state;
- attr->path_mtu = cmd.path_mtu;
- attr->path_mig_state = cmd.path_mig_state;
- attr->qkey = cmd.qkey;
- attr->rq_psn = cmd.rq_psn;
- attr->sq_psn = cmd.sq_psn;
- attr->dest_qp_num = cmd.dest_qp_num;
- attr->qp_access_flags = cmd.qp_access_flags;
- attr->pkey_index = cmd.pkey_index;
- attr->alt_pkey_index = cmd.alt_pkey_index;
- attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
- attr->max_rd_atomic = cmd.max_rd_atomic;
- attr->max_dest_rd_atomic = cmd.max_dest_rd_atomic;
- attr->min_rnr_timer = cmd.min_rnr_timer;
- attr->port_num = cmd.port_num;
- attr->timeout = cmd.timeout;
- attr->retry_cnt = cmd.retry_cnt;
- attr->rnr_retry = cmd.rnr_retry;
- attr->alt_port_num = cmd.alt_port_num;
- attr->alt_timeout = cmd.alt_timeout;
-
- memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
- attr->ah_attr.grh.flow_label = cmd.dest.flow_label;
- attr->ah_attr.grh.sgid_index = cmd.dest.sgid_index;
- attr->ah_attr.grh.hop_limit = cmd.dest.hop_limit;
- attr->ah_attr.grh.traffic_class = cmd.dest.traffic_class;
- attr->ah_attr.dlid = cmd.dest.dlid;
- attr->ah_attr.sl = cmd.dest.sl;
- attr->ah_attr.src_path_bits = cmd.dest.src_path_bits;
- attr->ah_attr.static_rate = cmd.dest.static_rate;
- attr->ah_attr.ah_flags = cmd.dest.is_global ? IB_AH_GRH : 0;
- attr->ah_attr.port_num = cmd.dest.port_num;
-
- memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
- attr->alt_ah_attr.grh.flow_label = cmd.alt_dest.flow_label;
- attr->alt_ah_attr.grh.sgid_index = cmd.alt_dest.sgid_index;
- attr->alt_ah_attr.grh.hop_limit = cmd.alt_dest.hop_limit;
- attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
- attr->alt_ah_attr.dlid = cmd.alt_dest.dlid;
- attr->alt_ah_attr.sl = cmd.alt_dest.sl;
- attr->alt_ah_attr.src_path_bits = cmd.alt_dest.src_path_bits;
- attr->alt_ah_attr.static_rate = cmd.alt_dest.static_rate;
- attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
- attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
+ attr->qp_state = cmd->base.qp_state;
+ attr->cur_qp_state = cmd->base.cur_qp_state;
+ attr->path_mtu = cmd->base.path_mtu;
+ attr->path_mig_state = cmd->base.path_mig_state;
+ attr->qkey = cmd->base.qkey;
+ attr->rq_psn = cmd->base.rq_psn;
+ attr->sq_psn = cmd->base.sq_psn;
+ attr->dest_qp_num = cmd->base.dest_qp_num;
+ attr->qp_access_flags = cmd->base.qp_access_flags;
+ attr->pkey_index = cmd->base.pkey_index;
+ attr->alt_pkey_index = cmd->base.alt_pkey_index;
+ attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify;
+ attr->max_rd_atomic = cmd->base.max_rd_atomic;
+ attr->max_dest_rd_atomic = cmd->base.max_dest_rd_atomic;
+ attr->min_rnr_timer = cmd->base.min_rnr_timer;
+ attr->port_num = cmd->base.port_num;
+ attr->timeout = cmd->base.timeout;
+ attr->retry_cnt = cmd->base.retry_cnt;
+ attr->rnr_retry = cmd->base.rnr_retry;
+ attr->alt_port_num = cmd->base.alt_port_num;
+ attr->alt_timeout = cmd->base.alt_timeout;
+ attr->rate_limit = cmd->rate_limit;
+
+ memcpy(attr->ah_attr.grh.dgid.raw, cmd->base.dest.dgid, 16);
+ attr->ah_attr.grh.flow_label = cmd->base.dest.flow_label;
+ attr->ah_attr.grh.sgid_index = cmd->base.dest.sgid_index;
+ attr->ah_attr.grh.hop_limit = cmd->base.dest.hop_limit;
+ attr->ah_attr.grh.traffic_class = cmd->base.dest.traffic_class;
+ attr->ah_attr.dlid = cmd->base.dest.dlid;
+ attr->ah_attr.sl = cmd->base.dest.sl;
+ attr->ah_attr.src_path_bits = cmd->base.dest.src_path_bits;
+ attr->ah_attr.static_rate = cmd->base.dest.static_rate;
+ attr->ah_attr.ah_flags = cmd->base.dest.is_global ?
+ IB_AH_GRH : 0;
+ attr->ah_attr.port_num = cmd->base.dest.port_num;
+
+ memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd->base.alt_dest.dgid, 16);
+ attr->alt_ah_attr.grh.flow_label = cmd->base.alt_dest.flow_label;
+ attr->alt_ah_attr.grh.sgid_index = cmd->base.alt_dest.sgid_index;
+ attr->alt_ah_attr.grh.hop_limit = cmd->base.alt_dest.hop_limit;
+ attr->alt_ah_attr.grh.traffic_class = cmd->base.alt_dest.traffic_class;
+ attr->alt_ah_attr.dlid = cmd->base.alt_dest.dlid;
+ attr->alt_ah_attr.sl = cmd->base.alt_dest.sl;
+ attr->alt_ah_attr.src_path_bits = cmd->base.alt_dest.src_path_bits;
+ attr->alt_ah_attr.static_rate = cmd->base.alt_dest.static_rate;
+ attr->alt_ah_attr.ah_flags = cmd->base.alt_dest.is_global ?
+ IB_AH_GRH : 0;
+ attr->alt_ah_attr.port_num = cmd->base.alt_dest.port_num;
if (qp->real_qp == qp) {
- ret = ib_resolve_eth_dmac(qp, attr, &cmd.attr_mask);
- if (ret)
- goto release_qp;
+ if (cmd->base.attr_mask & IB_QP_AV) {
+ ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
+ if (ret)
+ goto release_qp;
+ }
ret = qp->device->modify_qp(qp, attr,
- modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
+ modify_qp_mask(qp->qp_type,
+ cmd->base.attr_mask),
+ udata);
} else {
- ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask));
+ ret = ib_modify_qp(qp, attr,
+ modify_qp_mask(qp->qp_type,
+ cmd->base.attr_mask));
}
- if (ret)
- goto release_qp;
-
- ret = in_len;
-
release_qp:
put_qp_read(qp);
@@ -2425,6 +2419,68 @@ out:
return ret;
}
+ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
+ struct ib_device *ib_dev,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_ex_modify_qp cmd = {};
+ struct ib_udata udata;
+ int ret;
+
+ if (copy_from_user(&cmd.base, buf, sizeof(cmd.base)))
+ return -EFAULT;
+
+ if (cmd.base.attr_mask &
+ ~((IB_USER_LEGACY_LAST_QP_ATTR_MASK << 1) - 1))
+ return -EOPNOTSUPP;
+
+ INIT_UDATA(&udata, buf + sizeof(cmd.base), NULL,
+ in_len - sizeof(cmd.base), out_len);
+
+ ret = modify_qp(file, &cmd, &udata);
+ if (ret)
+ return ret;
+
+ return in_len;
+}
+
+int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file,
+ struct ib_device *ib_dev,
+ struct ib_udata *ucore,
+ struct ib_udata *uhw)
+{
+ struct ib_uverbs_ex_modify_qp cmd = {};
+ int ret;
+
+ /*
+ * Last bit is reserved for extending the attr_mask by
+ * using another field.
+ */
+ BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1 << 31));
+
+ if (ucore->inlen < sizeof(cmd.base))
+ return -EINVAL;
+
+ ret = ib_copy_from_udata(&cmd, ucore, min(sizeof(cmd), ucore->inlen));
+ if (ret)
+ return ret;
+
+ if (cmd.base.attr_mask &
+ ~((IB_USER_LAST_QP_ATTR_MASK << 1) - 1))
+ return -EOPNOTSUPP;
+
+ if (ucore->inlen > sizeof(cmd)) {
+ if (ib_is_udata_cleared(ucore, sizeof(cmd),
+ ucore->inlen - sizeof(cmd)))
+ return -EOPNOTSUPP;
+ }
+
+ ret = modify_qp(file, &cmd, uhw);
+
+ return ret;
+}
+
ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
struct ib_device *ib_dev,
const char __user *buf, int in_len,
@@ -2875,6 +2931,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
struct ib_ah *ah;
struct ib_ah_attr attr;
int ret;
+ struct ib_udata udata;
if (out_len < sizeof resp)
return -ENOSPC;
@@ -2882,6 +2939,10 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ INIT_UDATA(&udata, buf + sizeof(cmd),
+ (unsigned long)cmd.response + sizeof(resp),
+ in_len - sizeof(cmd), out_len - sizeof(resp));
+
uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
if (!uobj)
return -ENOMEM;
@@ -2908,12 +2969,16 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
memset(&attr.dmac, 0, sizeof(attr.dmac));
memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
- ah = ib_create_ah(pd, &attr);
+ ah = pd->device->create_ah(pd, &attr, &udata);
+
if (IS_ERR(ah)) {
ret = PTR_ERR(ah);
goto err_put;
}
+ ah->device = pd->device;
+ ah->pd = pd;
+ atomic_inc(&pd->usecnt);
ah->uobject = uobj;
uobj->object = ah;
@@ -3124,8 +3189,10 @@ static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec,
kern_spec_val = (void *)kern_spec +
sizeof(struct ib_uverbs_flow_spec_hdr);
kern_spec_mask = kern_spec_val + kern_filter_sz;
+ if (ib_spec->type == (IB_FLOW_SPEC_INNER | IB_FLOW_SPEC_VXLAN_TUNNEL))
+ return -EINVAL;
- switch (ib_spec->type) {
+ switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {
case IB_FLOW_SPEC_ETH:
ib_filter_sz = offsetof(struct ib_flow_eth_filter, real_sz);
actual_filter_sz = spec_filter_size(kern_spec_mask,
@@ -3175,6 +3242,21 @@ static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec,
memcpy(&ib_spec->tcp_udp.val, kern_spec_val, actual_filter_sz);
memcpy(&ib_spec->tcp_udp.mask, kern_spec_mask, actual_filter_sz);
break;
+ case IB_FLOW_SPEC_VXLAN_TUNNEL:
+ ib_filter_sz = offsetof(struct ib_flow_tunnel_filter, real_sz);
+ actual_filter_sz = spec_filter_size(kern_spec_mask,
+ kern_filter_sz,
+ ib_filter_sz);
+ if (actual_filter_sz <= 0)
+ return -EINVAL;
+ ib_spec->tunnel.size = sizeof(struct ib_flow_spec_tunnel);
+ memcpy(&ib_spec->tunnel.val, kern_spec_val, actual_filter_sz);
+ memcpy(&ib_spec->tunnel.mask, kern_spec_mask, actual_filter_sz);
+
+ if ((ntohl(ib_spec->tunnel.mask.tunnel_id)) >= BIT(24) ||
+ (ntohl(ib_spec->tunnel.val.tunnel_id)) >= BIT(24))
+ return -EINVAL;
+ break;
default:
return -EINVAL;
}
@@ -3745,7 +3827,6 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
err = PTR_ERR(flow_id);
goto err_free;
}
- flow_id->qp = qp;
flow_id->uobject = uobj;
uobj->object = flow_id;
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 44b1104eb168..813593550c4b 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -137,6 +137,7 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
[IB_USER_VERBS_EX_CMD_DESTROY_WQ] = ib_uverbs_ex_destroy_wq,
[IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL] = ib_uverbs_ex_create_rwq_ind_table,
[IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL] = ib_uverbs_ex_destroy_rwq_ind_table,
+ [IB_USER_VERBS_EX_CMD_MODIFY_QP] = ib_uverbs_ex_modify_qp,
};
static void ib_uverbs_add_one(struct ib_device *device);
@@ -746,8 +747,11 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
int srcu_key;
ssize_t ret;
- if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
+ if (!ib_safe_file_access(filp)) {
+ pr_err_once("uverbs_write: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n",
+ task_tgid_vnr(current), current->comm);
return -EACCES;
+ }
if (count < sizeof hdr)
return -EINVAL;
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 83687646da68..71580cc28c9e 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -315,7 +315,7 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
{
struct ib_ah *ah;
- ah = pd->device->create_ah(pd, ah_attr);
+ ah = pd->device->create_ah(pd, ah_attr, NULL);
if (!IS_ERR(ah)) {
ah->device = pd->device;
@@ -328,7 +328,7 @@ 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)
+int ib_get_rdma_header_version(const union rdma_network_hdr *hdr)
{
const struct iphdr *ip4h = (struct iphdr *)&hdr->roce4grh;
struct iphdr ip4h_checked;
@@ -359,6 +359,7 @@ static int ib_get_header_version(const union rdma_network_hdr *hdr)
return 4;
return 6;
}
+EXPORT_SYMBOL(ib_get_rdma_header_version);
static enum rdma_network_type ib_get_net_type_by_grh(struct ib_device *device,
u8 port_num,
@@ -369,7 +370,7 @@ static enum rdma_network_type ib_get_net_type_by_grh(struct ib_device *device,
if (rdma_protocol_ib(device, port_num))
return RDMA_NETWORK_IB;
- grh_version = ib_get_header_version((union rdma_network_hdr *)grh);
+ grh_version = ib_get_rdma_header_version((union rdma_network_hdr *)grh);
if (grh_version == 4)
return RDMA_NETWORK_IPV4;
@@ -415,9 +416,9 @@ static int get_sgid_index_from_eth(struct ib_device *device, u8 port_num,
&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)
+int ib_get_gids_from_rdma_hdr(const 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;
@@ -447,6 +448,7 @@ static int get_gids_from_rdma_hdr(union rdma_network_hdr *hdr,
return -EINVAL;
}
}
+EXPORT_SYMBOL(ib_get_gids_from_rdma_hdr);
int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
const struct ib_wc *wc, const struct ib_grh *grh,
@@ -469,8 +471,8 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
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);
+ ret = ib_get_gids_from_rdma_hdr((union rdma_network_hdr *)grh, net_type,
+ &sgid, &dgid);
if (ret)
return ret;
@@ -1014,6 +1016,7 @@ static const struct {
IB_QP_QKEY),
[IB_QPT_GSI] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
+ [IB_QPT_RAW_PACKET] = IB_QP_RATE_LIMIT,
}
}
},
@@ -1047,6 +1050,7 @@ static const struct {
IB_QP_QKEY),
[IB_QPT_GSI] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
+ [IB_QPT_RAW_PACKET] = IB_QP_RATE_LIMIT,
}
},
[IB_QPS_SQD] = {
@@ -1196,66 +1200,66 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
}
EXPORT_SYMBOL(ib_modify_qp_is_ok);
-int ib_resolve_eth_dmac(struct ib_qp *qp,
- struct ib_qp_attr *qp_attr, int *qp_attr_mask)
+int ib_resolve_eth_dmac(struct ib_device *device,
+ struct ib_ah_attr *ah_attr)
{
int ret = 0;
- if (*qp_attr_mask & IB_QP_AV) {
- if (qp_attr->ah_attr.port_num < rdma_start_port(qp->device) ||
- qp_attr->ah_attr.port_num > rdma_end_port(qp->device))
- return -EINVAL;
-
- if (!rdma_cap_eth_ah(qp->device, qp_attr->ah_attr.port_num))
- return 0;
-
- if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
- rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw,
- qp_attr->ah_attr.dmac);
- } else {
- 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,
- qp_attr->ah_attr.grh.sgid_index,
- &sgid, &sgid_attr);
-
- if (ret || !sgid_attr.ndev) {
- if (!ret)
- ret = -ENXIO;
- goto out;
- }
+ if (ah_attr->port_num < rdma_start_port(device) ||
+ ah_attr->port_num > rdma_end_port(device))
+ return -EINVAL;
- ifindex = sgid_attr.ndev->ifindex;
+ if (!rdma_cap_eth_ah(device, ah_attr->port_num))
+ return 0;
- ret = rdma_addr_find_l2_eth_by_grh(&sgid,
- &qp_attr->ah_attr.grh.dgid,
- qp_attr->ah_attr.dmac,
- NULL, &ifindex, &hop_limit);
+ if (rdma_link_local_addr((struct in6_addr *)ah_attr->grh.dgid.raw)) {
+ rdma_get_ll_mac((struct in6_addr *)ah_attr->grh.dgid.raw,
+ ah_attr->dmac);
+ } else {
+ union ib_gid sgid;
+ struct ib_gid_attr sgid_attr;
+ int ifindex;
+ int hop_limit;
+
+ ret = ib_query_gid(device,
+ ah_attr->port_num,
+ ah_attr->grh.sgid_index,
+ &sgid, &sgid_attr);
+
+ if (ret || !sgid_attr.ndev) {
+ if (!ret)
+ ret = -ENXIO;
+ goto out;
+ }
- dev_put(sgid_attr.ndev);
+ ifindex = sgid_attr.ndev->ifindex;
- qp_attr->ah_attr.grh.hop_limit = hop_limit;
- }
+ ret = rdma_addr_find_l2_eth_by_grh(&sgid,
+ &ah_attr->grh.dgid,
+ ah_attr->dmac,
+ NULL, &ifindex, &hop_limit);
+
+ dev_put(sgid_attr.ndev);
+
+ ah_attr->grh.hop_limit = hop_limit;
}
out:
return ret;
}
EXPORT_SYMBOL(ib_resolve_eth_dmac);
-
int ib_modify_qp(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask)
{
- int ret;
- ret = ib_resolve_eth_dmac(qp, qp_attr, &qp_attr_mask);
- if (ret)
- return ret;
+ if (qp_attr_mask & IB_QP_AV) {
+ int ret;
+
+ ret = ib_resolve_eth_dmac(qp->device, &qp_attr->ah_attr);
+ if (ret)
+ return ret;
+ }
return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
}
@@ -1734,8 +1738,10 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp,
return ERR_PTR(-ENOSYS);
flow_id = qp->device->create_flow(qp, flow_attr, domain);
- if (!IS_ERR(flow_id))
+ if (!IS_ERR(flow_id)) {
atomic_inc(&qp->usecnt);
+ flow_id->qp = qp;
+ }
return flow_id;
}
EXPORT_SYMBOL(ib_create_flow);
diff --git a/drivers/infiniband/hw/Makefile b/drivers/infiniband/hw/Makefile
index e7a5ed9f6f3f..ed553de2ca12 100644
--- a/drivers/infiniband/hw/Makefile
+++ b/drivers/infiniband/hw/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MLX4_INFINIBAND) += mlx4/
obj-$(CONFIG_MLX5_INFINIBAND) += mlx5/
obj-$(CONFIG_INFINIBAND_NES) += nes/
obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/
+obj-$(CONFIG_INFINIBAND_VMWARE_PVRDMA) += vmw_pvrdma/
obj-$(CONFIG_INFINIBAND_USNIC) += usnic/
obj-$(CONFIG_INFINIBAND_HFI1) += hfi1/
obj-$(CONFIG_INFINIBAND_HNS) += hns/
diff --git a/drivers/infiniband/hw/cxgb3/cxio_dbg.c b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
index 8bca6b4ec9af..445e89e5e7cf 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_dbg.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
@@ -45,10 +45,9 @@ void cxio_dump_tpt(struct cxio_rdev *rdev, u32 stag)
int size = 32;
m = kmalloc(sizeof(*m) + size, GFP_ATOMIC);
- if (!m) {
- PDBG("%s couldn't allocate memory.\n", __func__);
+ if (!m)
return;
- }
+
m->mem_id = MEM_PMRX;
m->addr = (stag>>8) * 32 + rdev->rnic_info.tpt_base;
m->len = size;
@@ -82,10 +81,9 @@ void cxio_dump_pbl(struct cxio_rdev *rdev, u32 pbl_addr, uint len, u8 shift)
size = npages * sizeof(u64);
m = kmalloc(sizeof(*m) + size, GFP_ATOMIC);
- if (!m) {
- PDBG("%s couldn't allocate memory.\n", __func__);
+ if (!m)
return;
- }
+
m->mem_id = MEM_PMRX;
m->addr = pbl_addr;
m->len = size;
@@ -144,10 +142,9 @@ void cxio_dump_rqt(struct cxio_rdev *rdev, u32 hwtid, int nents)
int rc;
m = kmalloc(sizeof(*m) + size, GFP_ATOMIC);
- if (!m) {
- PDBG("%s couldn't allocate memory.\n", __func__);
+ if (!m)
return;
- }
+
m->mem_id = MEM_PMRX;
m->addr = ((hwtid)<<10) + rdev->rnic_info.rqt_base;
m->len = size;
@@ -177,10 +174,9 @@ void cxio_dump_tcb(struct cxio_rdev *rdev, u32 hwtid)
int rc;
m = kmalloc(sizeof(*m) + size, GFP_ATOMIC);
- if (!m) {
- PDBG("%s couldn't allocate memory.\n", __func__);
+ if (!m)
return;
- }
+
m->mem_id = MEM_CM;
m->addr = hwtid * size;
m->len = size;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index cba57bb53dba..9d5fe1853da4 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -62,7 +62,8 @@
#include "common.h"
static struct ib_ah *iwch_ah_create(struct ib_pd *pd,
- struct ib_ah_attr *ah_attr)
+ struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
{
return ERR_PTR(-ENOSYS);
}
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 4e5baf4fe15e..516b0ae6dc3f 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -828,8 +828,10 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
}
rdev->status_page = (struct t4_dev_status_page *)
__get_free_page(GFP_KERNEL);
- if (!rdev->status_page)
+ if (!rdev->status_page) {
+ err = -ENOMEM;
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;
@@ -841,8 +843,6 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
if (rdev->wr_log) {
rdev->wr_log_size = 1 << c4iw_wr_log_size_order;
atomic_set(&rdev->wr_log_idx, 0);
- } else {
- pr_err(MOD "error allocating wr_log. Logging disabled\n");
}
}
@@ -1424,8 +1424,6 @@ static void recover_queues(struct uld_ctx *ctx)
qp_list.qps = kzalloc(count * sizeof *qp_list.qps, GFP_ATOMIC);
if (!qp_list.qps) {
- printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n",
- pci_name(ctx->lldi.pdev));
spin_unlock_irq(&ctx->dev->lock);
return;
}
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index 645e606a17c5..49b51b7e0fd7 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -59,7 +59,9 @@ module_param(fastreg_support, int, 0644);
MODULE_PARM_DESC(fastreg_support, "Advertise fastreg support (default=1)");
static struct ib_ah *c4iw_ah_create(struct ib_pd *pd,
- struct ib_ah_attr *ah_attr)
+ struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
+
{
return ERR_PTR(-ENOSYS);
}
diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c
index 67ea85a56945..7a3d906b3671 100644
--- a/drivers/infiniband/hw/hfi1/affinity.c
+++ b/drivers/infiniband/hw/hfi1/affinity.c
@@ -125,6 +125,7 @@ int node_affinity_init(void)
cpumask_weight(topology_sibling_cpumask(
cpumask_first(&node_affinity.proc.mask)
));
+ node_affinity.num_possible_nodes = num_possible_nodes();
node_affinity.num_online_nodes = num_online_nodes();
node_affinity.num_online_cpus = num_online_cpus();
@@ -135,7 +136,7 @@ int node_affinity_init(void)
*/
init_real_cpu_mask();
- hfi1_per_node_cntr = kcalloc(num_possible_nodes(),
+ hfi1_per_node_cntr = kcalloc(node_affinity.num_possible_nodes,
sizeof(*hfi1_per_node_cntr), GFP_KERNEL);
if (!hfi1_per_node_cntr)
return -ENOMEM;
diff --git a/drivers/infiniband/hw/hfi1/affinity.h b/drivers/infiniband/hw/hfi1/affinity.h
index 42e63316afd1..e78c7aa094e0 100644
--- a/drivers/infiniband/hw/hfi1/affinity.h
+++ b/drivers/infiniband/hw/hfi1/affinity.h
@@ -70,14 +70,6 @@ struct cpu_mask_set {
uint gen;
};
-struct hfi1_affinity {
- struct cpu_mask_set def_intr;
- struct cpu_mask_set rcv_intr;
- struct cpumask real_cpu_mask;
- /* spin lock to protect affinity struct */
- spinlock_t lock;
-};
-
struct hfi1_msix_entry;
/* Initialize non-HT cpu cores mask */
@@ -115,6 +107,7 @@ struct hfi1_affinity_node_list {
struct cpumask real_cpu_mask;
struct cpu_mask_set proc;
int num_core_siblings;
+ int num_possible_nodes;
int num_online_nodes;
int num_online_cpus;
struct mutex lock; /* protects affinity nodes */
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 24d0820873cf..ef72bc2a9e1d 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -8477,7 +8477,10 @@ static int do_8051_command(
*/
if (type == HCMD_WRITE_LCB_CSR) {
in_data |= ((*out_data) & 0xffffffffffull) << 8;
- reg = ((((*out_data) >> 40) & 0xff) <<
+ /* must preserve COMPLETED - it is tied to hardware */
+ reg = read_csr(dd, DC_DC8051_CFG_EXT_DEV_0);
+ reg &= DC_DC8051_CFG_EXT_DEV_0_COMPLETED_SMASK;
+ reg |= ((((*out_data) >> 40) & 0xff) <<
DC_DC8051_CFG_EXT_DEV_0_RETURN_CODE_SHIFT)
| ((((*out_data) >> 48) & 0xffff) <<
DC_DC8051_CFG_EXT_DEV_0_RSP_DATA_SHIFT);
@@ -9556,11 +9559,11 @@ int bringup_serdes(struct hfi1_pportdata *ppd)
if (HFI1_CAP_IS_KSET(EXTENDED_PSN))
add_rcvctrl(dd, RCV_CTRL_RCV_EXTENDED_PSN_ENABLE_SMASK);
- guid = ppd->guid;
+ guid = ppd->guids[HFI1_PORT_GUID_INDEX];
if (!guid) {
if (dd->base_guid)
guid = dd->base_guid + ppd->port - 1;
- ppd->guid = guid;
+ ppd->guids[HFI1_PORT_GUID_INDEX] = guid;
}
/* Set linkinit_reason on power up per OPA spec */
diff --git a/drivers/infiniband/hw/hfi1/chip_registers.h b/drivers/infiniband/hw/hfi1/chip_registers.h
index 5b9993899789..5bfa839d1c48 100644
--- a/drivers/infiniband/hw/hfi1/chip_registers.h
+++ b/drivers/infiniband/hw/hfi1/chip_registers.h
@@ -415,6 +415,9 @@
#define ASIC_CFG_SBUS_REQUEST_DATA_IN_SHIFT 32
#define ASIC_CFG_SBUS_REQUEST_RECEIVER_ADDR_SHIFT 0
#define ASIC_CFG_SCRATCH (ASIC + 0x000000000020)
+#define ASIC_CFG_SCRATCH_1 (ASIC_CFG_SCRATCH + 0x08)
+#define ASIC_CFG_SCRATCH_2 (ASIC_CFG_SCRATCH + 0x10)
+#define ASIC_CFG_SCRATCH_3 (ASIC_CFG_SCRATCH + 0x18)
#define ASIC_CFG_THERM_POLL_EN (ASIC + 0x000000000050)
#define ASIC_EEP_ADDR_CMD (ASIC + 0x000000000308)
#define ASIC_EEP_ADDR_CMD_EP_ADDR_MASK 0xFFFFFFull
diff --git a/drivers/infiniband/hw/hfi1/debugfs.c b/drivers/infiniband/hw/hfi1/debugfs.c
index 632ba21759ab..8725f4c086cf 100644
--- a/drivers/infiniband/hw/hfi1/debugfs.c
+++ b/drivers/infiniband/hw/hfi1/debugfs.c
@@ -541,6 +541,114 @@ static ssize_t asic_flags_write(struct file *file, const char __user *buf,
return ret;
}
+/* read the dc8051 memory */
+static ssize_t dc8051_memory_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct hfi1_pportdata *ppd = private2ppd(file);
+ ssize_t rval;
+ void *tmp;
+ loff_t start, end;
+
+ /* the checks below expect the position to be positive */
+ if (*ppos < 0)
+ return -EINVAL;
+
+ tmp = kzalloc(DC8051_DATA_MEM_SIZE, GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+
+ /*
+ * Fill in the requested portion of the temporary buffer from the
+ * 8051 memory. The 8051 memory read is done in terms of 8 bytes.
+ * Adjust start and end to fit. Skip reading anything if out of
+ * range.
+ */
+ start = *ppos & ~0x7; /* round down */
+ if (start < DC8051_DATA_MEM_SIZE) {
+ end = (*ppos + count + 7) & ~0x7; /* round up */
+ if (end > DC8051_DATA_MEM_SIZE)
+ end = DC8051_DATA_MEM_SIZE;
+ rval = read_8051_data(ppd->dd, start, end - start,
+ (u64 *)(tmp + start));
+ if (rval)
+ goto done;
+ }
+
+ rval = simple_read_from_buffer(buf, count, ppos, tmp,
+ DC8051_DATA_MEM_SIZE);
+done:
+ kfree(tmp);
+ return rval;
+}
+
+static ssize_t debugfs_lcb_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct hfi1_pportdata *ppd = private2ppd(file);
+ struct hfi1_devdata *dd = ppd->dd;
+ unsigned long total, csr_off;
+ u64 data;
+
+ if (*ppos < 0)
+ return -EINVAL;
+ /* only read 8 byte quantities */
+ if ((count % 8) != 0)
+ return -EINVAL;
+ /* offset must be 8-byte aligned */
+ if ((*ppos % 8) != 0)
+ return -EINVAL;
+ /* do nothing if out of range or zero count */
+ if (*ppos >= (LCB_END - LCB_START) || !count)
+ return 0;
+ /* reduce count if needed */
+ if (*ppos + count > LCB_END - LCB_START)
+ count = (LCB_END - LCB_START) - *ppos;
+
+ csr_off = LCB_START + *ppos;
+ for (total = 0; total < count; total += 8, csr_off += 8) {
+ if (read_lcb_csr(dd, csr_off, (u64 *)&data))
+ break; /* failed */
+ if (put_user(data, (unsigned long __user *)(buf + total)))
+ break;
+ }
+ *ppos += total;
+ return total;
+}
+
+static ssize_t debugfs_lcb_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct hfi1_pportdata *ppd = private2ppd(file);
+ struct hfi1_devdata *dd = ppd->dd;
+ unsigned long total, csr_off, data;
+
+ if (*ppos < 0)
+ return -EINVAL;
+ /* only write 8 byte quantities */
+ if ((count % 8) != 0)
+ return -EINVAL;
+ /* offset must be 8-byte aligned */
+ if ((*ppos % 8) != 0)
+ return -EINVAL;
+ /* do nothing if out of range or zero count */
+ if (*ppos >= (LCB_END - LCB_START) || !count)
+ return 0;
+ /* reduce count if needed */
+ if (*ppos + count > LCB_END - LCB_START)
+ count = (LCB_END - LCB_START) - *ppos;
+
+ csr_off = LCB_START + *ppos;
+ for (total = 0; total < count; total += 8, csr_off += 8) {
+ if (get_user(data, (unsigned long __user *)(buf + total)))
+ break;
+ if (write_lcb_csr(dd, csr_off, data))
+ break; /* failed */
+ }
+ *ppos += total;
+ return total;
+}
+
/*
* read the per-port QSFP data for ppd
*/
@@ -931,6 +1039,8 @@ static const struct counter_info port_cntr_ops[] = {
DEBUGFS_XOPS("qsfp2", qsfp2_debugfs_read, qsfp2_debugfs_write,
qsfp2_debugfs_open, qsfp2_debugfs_release),
DEBUGFS_OPS("asic_flags", asic_flags_read, asic_flags_write),
+ DEBUGFS_OPS("dc8051_memory", dc8051_memory_read, NULL),
+ DEBUGFS_OPS("lcb", debugfs_lcb_read, debugfs_lcb_write),
};
static void *_sdma_cpu_list_seq_start(struct seq_file *s, loff_t *pos)
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c
index c5efff29c147..4fbaee68012b 100644
--- a/drivers/infiniband/hw/hfi1/driver.c
+++ b/drivers/infiniband/hw/hfi1/driver.c
@@ -795,8 +795,7 @@ static inline void process_rcv_qp_work(struct hfi1_packet *packet)
hfi1_schedule_send(qp);
spin_unlock_irqrestore(&qp->s_lock, flags);
}
- if (atomic_dec_and_test(&qp->refcount))
- wake_up(&qp->wait);
+ rvt_put_qp(qp);
}
}
diff --git a/drivers/infiniband/hw/hfi1/eprom.c b/drivers/infiniband/hw/hfi1/eprom.c
index e70c223801b4..26da124c88e2 100644
--- a/drivers/infiniband/hw/hfi1/eprom.c
+++ b/drivers/infiniband/hw/hfi1/eprom.c
@@ -207,6 +207,40 @@ done_asic:
/* magic character sequence that trails an image */
#define IMAGE_TRAIL_MAGIC "egamiAPO"
+/* EPROM file types */
+#define HFI1_EFT_PLATFORM_CONFIG 2
+
+/* segment size - 128 KiB */
+#define SEG_SIZE (128 * 1024)
+
+struct hfi1_eprom_footer {
+ u32 oprom_size; /* size of the oprom, in bytes */
+ u16 num_table_entries;
+ u16 version; /* version of this footer */
+ u32 magic; /* must be last */
+};
+
+struct hfi1_eprom_table_entry {
+ u32 type; /* file type */
+ u32 offset; /* file offset from start of EPROM */
+ u32 size; /* file size, in bytes */
+};
+
+/*
+ * Calculate the max number of table entries that will fit within a directory
+ * buffer of size 'dir_size'.
+ */
+#define MAX_TABLE_ENTRIES(dir_size) \
+ (((dir_size) - sizeof(struct hfi1_eprom_footer)) / \
+ sizeof(struct hfi1_eprom_table_entry))
+
+#define DIRECTORY_SIZE(n) (sizeof(struct hfi1_eprom_footer) + \
+ (sizeof(struct hfi1_eprom_table_entry) * (n)))
+
+#define MAGIC4(a, b, c, d) ((d) << 24 | (c) << 16 | (b) << 8 | (a))
+#define FOOTER_MAGIC MAGIC4('e', 'p', 'r', 'm')
+#define FOOTER_VERSION 1
+
/*
* Read all of partition 1. The actual file is at the front. Adjust
* the returned size if a trailing image magic is found.
@@ -242,6 +276,167 @@ static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
}
/*
+ * The segment magic has been checked. There is a footer and table of
+ * contents present.
+ *
+ * directory is a u32 aligned buffer of size EP_PAGE_SIZE.
+ */
+static int read_segment_platform_config(struct hfi1_devdata *dd,
+ void *directory, void **data, u32 *size)
+{
+ struct hfi1_eprom_footer *footer;
+ struct hfi1_eprom_table_entry *table;
+ struct hfi1_eprom_table_entry *entry;
+ void *buffer = NULL;
+ void *table_buffer = NULL;
+ int ret, i;
+ u32 directory_size;
+ u32 seg_base, seg_offset;
+ u32 bytes_available, ncopied, to_copy;
+
+ /* the footer is at the end of the directory */
+ footer = (struct hfi1_eprom_footer *)
+ (directory + EP_PAGE_SIZE - sizeof(*footer));
+
+ /* make sure the structure version is supported */
+ if (footer->version != FOOTER_VERSION)
+ return -EINVAL;
+
+ /* oprom size cannot be larger than a segment */
+ if (footer->oprom_size >= SEG_SIZE)
+ return -EINVAL;
+
+ /* the file table must fit in a segment with the oprom */
+ if (footer->num_table_entries >
+ MAX_TABLE_ENTRIES(SEG_SIZE - footer->oprom_size))
+ return -EINVAL;
+
+ /* find the file table start, which precedes the footer */
+ directory_size = DIRECTORY_SIZE(footer->num_table_entries);
+ if (directory_size <= EP_PAGE_SIZE) {
+ /* the file table fits into the directory buffer handed in */
+ table = (struct hfi1_eprom_table_entry *)
+ (directory + EP_PAGE_SIZE - directory_size);
+ } else {
+ /* need to allocate and read more */
+ table_buffer = kmalloc(directory_size, GFP_KERNEL);
+ if (!table_buffer)
+ return -ENOMEM;
+ ret = read_length(dd, SEG_SIZE - directory_size,
+ directory_size, table_buffer);
+ if (ret)
+ goto done;
+ table = table_buffer;
+ }
+
+ /* look for the platform configuration file in the table */
+ for (entry = NULL, i = 0; i < footer->num_table_entries; i++) {
+ if (table[i].type == HFI1_EFT_PLATFORM_CONFIG) {
+ entry = &table[i];
+ break;
+ }
+ }
+ if (!entry) {
+ ret = -ENOENT;
+ goto done;
+ }
+
+ /*
+ * Sanity check on the configuration file size - it should never
+ * be larger than 4 KiB.
+ */
+ if (entry->size > (4 * 1024)) {
+ dd_dev_err(dd, "Bad configuration file size 0x%x\n",
+ entry->size);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* check for bogus offset and size that wrap when added together */
+ if (entry->offset + entry->size < entry->offset) {
+ dd_dev_err(dd,
+ "Bad configuration file start + size 0x%x+0x%x\n",
+ entry->offset, entry->size);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* allocate the buffer to return */
+ buffer = kmalloc(entry->size, GFP_KERNEL);
+ if (!buffer) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ /*
+ * Extract the file by looping over segments until it is fully read.
+ */
+ seg_offset = entry->offset % SEG_SIZE;
+ seg_base = entry->offset - seg_offset;
+ ncopied = 0;
+ while (ncopied < entry->size) {
+ /* calculate data bytes available in this segment */
+
+ /* start with the bytes from the current offset to the end */
+ bytes_available = SEG_SIZE - seg_offset;
+ /* subtract off footer and table from segment 0 */
+ if (seg_base == 0) {
+ /*
+ * Sanity check: should not have a starting point
+ * at or within the directory.
+ */
+ if (bytes_available <= directory_size) {
+ dd_dev_err(dd,
+ "Bad configuration file - offset 0x%x within footer+table\n",
+ entry->offset);
+ ret = -EINVAL;
+ goto done;
+ }
+ bytes_available -= directory_size;
+ }
+
+ /* calculate bytes wanted */
+ to_copy = entry->size - ncopied;
+
+ /* max out at the available bytes in this segment */
+ if (to_copy > bytes_available)
+ to_copy = bytes_available;
+
+ /*
+ * Read from the EPROM.
+ *
+ * The sanity check for entry->offset is done in read_length().
+ * The EPROM offset is validated against what the hardware
+ * addressing supports. In addition, if the offset is larger
+ * than the actual EPROM, it silently wraps. It will work
+ * fine, though the reader may not get what they expected
+ * from the EPROM.
+ */
+ ret = read_length(dd, seg_base + seg_offset, to_copy,
+ buffer + ncopied);
+ if (ret)
+ goto done;
+
+ ncopied += to_copy;
+
+ /* set up for next segment */
+ seg_offset = footer->oprom_size;
+ seg_base += SEG_SIZE;
+ }
+
+ /* success */
+ ret = 0;
+ *data = buffer;
+ *size = entry->size;
+
+done:
+ kfree(table_buffer);
+ if (ret)
+ kfree(buffer);
+ return ret;
+}
+
+/*
* Read the platform configuration file from the EPROM.
*
* On success, an allocated buffer containing the data and its size are
@@ -253,6 +448,7 @@ static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
* -EBUSY - not able to acquire access to the EPROM
* -ENOENT - no recognizable file written
* -ENOMEM - buffer could not be allocated
+ * -EINVAL - invalid EPROM contentents found
*/
int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size)
{
@@ -266,21 +462,20 @@ int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size)
if (ret)
return -EBUSY;
- /* read the last page of P0 for the EPROM format magic */
- ret = read_length(dd, P1_START - EP_PAGE_SIZE, EP_PAGE_SIZE, directory);
+ /* read the last page of the segment for the EPROM format magic */
+ ret = read_length(dd, SEG_SIZE - EP_PAGE_SIZE, EP_PAGE_SIZE, directory);
if (ret)
goto done;
- /* last dword of P0 contains a magic indicator */
- if (directory[EP_PAGE_DWORDS - 1] == 0) {
+ /* last dword of the segment contains a magic value */
+ if (directory[EP_PAGE_DWORDS - 1] == FOOTER_MAGIC) {
+ /* segment format */
+ ret = read_segment_platform_config(dd, directory, data, size);
+ } else {
/* partition format */
ret = read_partition_platform_config(dd, data, size);
- goto done;
}
- /* nothing recognized */
- ret = -ENOENT;
-
done:
release_chip_resource(dd, CR_EPROM);
return ret;
diff --git a/drivers/infiniband/hw/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c
index 13db8eb4f4ec..0dd50cdb039a 100644
--- a/drivers/infiniband/hw/hfi1/firmware.c
+++ b/drivers/infiniband/hw/hfi1/firmware.c
@@ -239,6 +239,16 @@ static const u8 all_fabric_serdes_broadcast = 0xe1;
const u8 pcie_serdes_broadcast[2] = { 0xe2, 0xe3 };
static const u8 all_pcie_serdes_broadcast = 0xe0;
+static const u32 platform_config_table_limits[PLATFORM_CONFIG_TABLE_MAX] = {
+ 0,
+ SYSTEM_TABLE_MAX,
+ PORT_TABLE_MAX,
+ RX_PRESET_TABLE_MAX,
+ TX_PRESET_TABLE_MAX,
+ QSFP_ATTEN_TABLE_MAX,
+ VARIABLE_SETTINGS_TABLE_MAX
+};
+
/* forwards */
static void dispose_one_firmware(struct firmware_details *fdet);
static int load_fabric_serdes_firmware(struct hfi1_devdata *dd,
@@ -263,11 +273,13 @@ static int __read_8051_data(struct hfi1_devdata *dd, u32 addr, u64 *result)
u64 reg;
int count;
- /* start the read at the given address */
- reg = ((addr & DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_MASK)
- << DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_SHIFT)
- | DC_DC8051_CFG_RAM_ACCESS_CTRL_READ_ENA_SMASK;
+ /* step 1: set the address, clear enable */
+ reg = (addr & DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_MASK)
+ << DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_SHIFT;
write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL, reg);
+ /* step 2: enable */
+ write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL,
+ reg | DC_DC8051_CFG_RAM_ACCESS_CTRL_READ_ENA_SMASK);
/* wait until ACCESS_COMPLETED is set */
count = 0;
@@ -707,6 +719,9 @@ static int obtain_firmware(struct hfi1_devdata *dd)
&dd->pcidev->dev);
if (err) {
platform_config = NULL;
+ dd_dev_err(dd,
+ "%s: No default platform config file found\n",
+ __func__);
goto done;
}
dd->platform_config.data = platform_config->data;
@@ -1761,8 +1776,17 @@ int parse_platform_config(struct hfi1_devdata *dd)
u32 record_idx = 0, table_type = 0, table_length_dwords = 0;
int ret = -EINVAL; /* assume failure */
+ /*
+ * For integrated devices that did not fall back to the default file,
+ * the SI tuning information for active channels is acquired from the
+ * scratch register bitmap, thus there is no platform config to parse.
+ * Skip parsing in these situations.
+ */
+ if (is_integrated(dd) && !platform_config_load)
+ return 0;
+
if (!dd->platform_config.data) {
- dd_dev_info(dd, "%s: Missing config file\n", __func__);
+ dd_dev_err(dd, "%s: Missing config file\n", __func__);
goto bail;
}
ptr = (u32 *)dd->platform_config.data;
@@ -1770,7 +1794,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
magic_num = *ptr;
ptr++;
if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) {
- dd_dev_info(dd, "%s: Bad config file\n", __func__);
+ dd_dev_err(dd, "%s: Bad config file\n", __func__);
goto bail;
}
@@ -1797,9 +1821,9 @@ int parse_platform_config(struct hfi1_devdata *dd)
header1 = *ptr;
header2 = *(ptr + 1);
if (header1 != ~header2) {
- dd_dev_info(dd, "%s: Failed validation at offset %ld\n",
- __func__, (ptr - (u32 *)
- dd->platform_config.data));
+ dd_dev_err(dd, "%s: Failed validation at offset %ld\n",
+ __func__, (ptr - (u32 *)
+ dd->platform_config.data));
goto bail;
}
@@ -1841,11 +1865,11 @@ int parse_platform_config(struct hfi1_devdata *dd)
table_length_dwords;
break;
default:
- dd_dev_info(dd,
- "%s: Unknown data table %d, offset %ld\n",
- __func__, table_type,
- (ptr - (u32 *)
- dd->platform_config.data));
+ dd_dev_err(dd,
+ "%s: Unknown data table %d, offset %ld\n",
+ __func__, table_type,
+ (ptr - (u32 *)
+ dd->platform_config.data));
goto bail; /* We don't trust this file now */
}
pcfgcache->config_tables[table_type].table = ptr;
@@ -1865,11 +1889,11 @@ int parse_platform_config(struct hfi1_devdata *dd)
case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
break;
default:
- dd_dev_info(dd,
- "%s: Unknown meta table %d, offset %ld\n",
- __func__, table_type,
- (ptr -
- (u32 *)dd->platform_config.data));
+ dd_dev_err(dd,
+ "%s: Unknown meta table %d, offset %ld\n",
+ __func__, table_type,
+ (ptr -
+ (u32 *)dd->platform_config.data));
goto bail; /* We don't trust this file now */
}
pcfgcache->config_tables[table_type].table_metadata =
@@ -1884,10 +1908,9 @@ int parse_platform_config(struct hfi1_devdata *dd)
/* Jump the table */
ptr += table_length_dwords;
if (crc != *ptr) {
- dd_dev_info(dd, "%s: Failed CRC check at offset %ld\n",
- __func__, (ptr -
- (u32 *)
- dd->platform_config.data));
+ dd_dev_err(dd, "%s: Failed CRC check at offset %ld\n",
+ __func__, (ptr -
+ (u32 *)dd->platform_config.data));
goto bail;
}
/* Jump the CRC DWORD */
@@ -1901,6 +1924,84 @@ bail:
return ret;
}
+static void get_integrated_platform_config_field(
+ struct hfi1_devdata *dd,
+ enum platform_config_table_type_encoding table_type,
+ int field_index, u32 *data)
+{
+ struct hfi1_pportdata *ppd = dd->pport;
+ u8 *cache = ppd->qsfp_info.cache;
+ u32 tx_preset = 0;
+
+ switch (table_type) {
+ case PLATFORM_CONFIG_SYSTEM_TABLE:
+ if (field_index == SYSTEM_TABLE_QSFP_POWER_CLASS_MAX)
+ *data = ppd->max_power_class;
+ else if (field_index == SYSTEM_TABLE_QSFP_ATTENUATION_DEFAULT_25G)
+ *data = ppd->default_atten;
+ break;
+ case PLATFORM_CONFIG_PORT_TABLE:
+ if (field_index == PORT_TABLE_PORT_TYPE)
+ *data = ppd->port_type;
+ else if (field_index == PORT_TABLE_LOCAL_ATTEN_25G)
+ *data = ppd->local_atten;
+ else if (field_index == PORT_TABLE_REMOTE_ATTEN_25G)
+ *data = ppd->remote_atten;
+ break;
+ case PLATFORM_CONFIG_RX_PRESET_TABLE:
+ if (field_index == RX_PRESET_TABLE_QSFP_RX_CDR_APPLY)
+ *data = (ppd->rx_preset & QSFP_RX_CDR_APPLY_SMASK) >>
+ QSFP_RX_CDR_APPLY_SHIFT;
+ else if (field_index == RX_PRESET_TABLE_QSFP_RX_EMP_APPLY)
+ *data = (ppd->rx_preset & QSFP_RX_EMP_APPLY_SMASK) >>
+ QSFP_RX_EMP_APPLY_SHIFT;
+ else if (field_index == RX_PRESET_TABLE_QSFP_RX_AMP_APPLY)
+ *data = (ppd->rx_preset & QSFP_RX_AMP_APPLY_SMASK) >>
+ QSFP_RX_AMP_APPLY_SHIFT;
+ else if (field_index == RX_PRESET_TABLE_QSFP_RX_CDR)
+ *data = (ppd->rx_preset & QSFP_RX_CDR_SMASK) >>
+ QSFP_RX_CDR_SHIFT;
+ else if (field_index == RX_PRESET_TABLE_QSFP_RX_EMP)
+ *data = (ppd->rx_preset & QSFP_RX_EMP_SMASK) >>
+ QSFP_RX_EMP_SHIFT;
+ else if (field_index == RX_PRESET_TABLE_QSFP_RX_AMP)
+ *data = (ppd->rx_preset & QSFP_RX_AMP_SMASK) >>
+ QSFP_RX_AMP_SHIFT;
+ break;
+ case PLATFORM_CONFIG_TX_PRESET_TABLE:
+ if (cache[QSFP_EQ_INFO_OFFS] & 0x4)
+ tx_preset = ppd->tx_preset_eq;
+ else
+ tx_preset = ppd->tx_preset_noeq;
+ if (field_index == TX_PRESET_TABLE_PRECUR)
+ *data = (tx_preset & TX_PRECUR_SMASK) >>
+ TX_PRECUR_SHIFT;
+ else if (field_index == TX_PRESET_TABLE_ATTN)
+ *data = (tx_preset & TX_ATTN_SMASK) >>
+ TX_ATTN_SHIFT;
+ else if (field_index == TX_PRESET_TABLE_POSTCUR)
+ *data = (tx_preset & TX_POSTCUR_SMASK) >>
+ TX_POSTCUR_SHIFT;
+ else if (field_index == TX_PRESET_TABLE_QSFP_TX_CDR_APPLY)
+ *data = (tx_preset & QSFP_TX_CDR_APPLY_SMASK) >>
+ QSFP_TX_CDR_APPLY_SHIFT;
+ else if (field_index == TX_PRESET_TABLE_QSFP_TX_EQ_APPLY)
+ *data = (tx_preset & QSFP_TX_EQ_APPLY_SMASK) >>
+ QSFP_TX_EQ_APPLY_SHIFT;
+ else if (field_index == TX_PRESET_TABLE_QSFP_TX_CDR)
+ *data = (tx_preset & QSFP_TX_CDR_SMASK) >>
+ QSFP_TX_CDR_SHIFT;
+ else if (field_index == TX_PRESET_TABLE_QSFP_TX_EQ)
+ *data = (tx_preset & QSFP_TX_EQ_SMASK) >>
+ QSFP_TX_EQ_SHIFT;
+ break;
+ case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
+ case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
+ default:
+ break;
+ }
+}
+
static int get_platform_fw_field_metadata(struct hfi1_devdata *dd, int table,
int field, u32 *field_len_bits,
u32 *field_start_bits)
@@ -1976,6 +2077,15 @@ int get_platform_config_field(struct hfi1_devdata *dd,
else
return -EINVAL;
+ if (is_integrated(dd) && !platform_config_load) {
+ /*
+ * Use saved configuration from ppd for integrated platforms
+ */
+ get_integrated_platform_config_field(dd, table_type,
+ field_index, data);
+ return 0;
+ }
+
ret = get_platform_fw_field_metadata(dd, table_type, field_index,
&field_len_bits,
&field_start_bits);
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
index cc87fd4e534b..751a0fb29fa5 100644
--- a/drivers/infiniband/hw/hfi1/hfi.h
+++ b/drivers/infiniband/hw/hfi1/hfi.h
@@ -492,6 +492,9 @@ struct rvt_sge_state;
#define HFI1_MIN_VLS_SUPPORTED 1
#define HFI1_MAX_VLS_SUPPORTED 8
+#define HFI1_GUIDS_PER_PORT 5
+#define HFI1_PORT_GUID_INDEX 0
+
static inline void incr_cntr64(u64 *cntr)
{
if (*cntr < (u64)-1LL)
@@ -559,11 +562,20 @@ struct hfi1_pportdata {
struct kobject vl2mtu_kobj;
/* PHY support */
- u32 port_type;
struct qsfp_data qsfp_info;
+ /* Values for SI tuning of SerDes */
+ u32 port_type;
+ u32 tx_preset_eq;
+ u32 tx_preset_noeq;
+ u32 rx_preset;
+ u8 local_atten;
+ u8 remote_atten;
+ u8 default_atten;
+ u8 max_power_class;
+
+ /* GUIDs for this interface, in host order, guids[0] is a port guid */
+ u64 guids[HFI1_GUIDS_PER_PORT];
- /* GUID for this interface, in host order */
- u64 guid;
/* GUID for peer interface, in host order */
u64 neighbor_guid;
@@ -826,32 +838,29 @@ struct hfi1_devdata {
u8 __iomem *kregend;
/* physical address of chip for io_remap, etc. */
resource_size_t physaddr;
- /* receive context data */
- struct hfi1_ctxtdata **rcd;
+ /* Per VL data. Enough for all VLs but not all elements are set/used. */
+ struct per_vl_data vld[PER_VL_SEND_CONTEXTS];
/* send context data */
struct send_context_info *send_contexts;
/* map hardware send contexts to software index */
u8 *hw_to_sw;
/* spinlock for allocating and releasing send context resources */
spinlock_t sc_lock;
- /* Per VL data. Enough for all VLs but not all elements are set/used. */
- struct per_vl_data vld[PER_VL_SEND_CONTEXTS];
/* lock for pio_map */
spinlock_t pio_map_lock;
+ /* Send Context initialization lock. */
+ spinlock_t sc_init_lock;
+ /* lock for sdma_map */
+ spinlock_t sde_map_lock;
/* array of kernel send contexts */
struct send_context **kernel_send_context;
/* array of vl maps */
struct pio_vl_map __rcu *pio_map;
- /* seqlock for sc2vl */
- seqlock_t sc2vl_lock;
- u64 sc2vl[4];
- /* Send Context initialization lock. */
- spinlock_t sc_init_lock;
+ /* default flags to last descriptor */
+ u64 default_desc1;
/* fields common to all SDMA engines */
- /* default flags to last descriptor */
- u64 default_desc1;
volatile __le64 *sdma_heads_dma; /* DMA'ed by chip */
dma_addr_t sdma_heads_phys;
void *sdma_pad_dma; /* DMA'ed by chip */
@@ -862,8 +871,6 @@ struct hfi1_devdata {
u32 chip_sdma_engines;
/* num used */
u32 num_sdma;
- /* lock for sdma_map */
- spinlock_t sde_map_lock;
/* array of engines sized by num_sdma */
struct sdma_engine *per_sdma;
/* array of vl maps */
@@ -872,14 +879,11 @@ struct hfi1_devdata {
wait_queue_head_t sdma_unfreeze_wq;
atomic_t sdma_unfreeze_count;
+ u32 lcb_access_count; /* count of LCB users */
+
/* common data between shared ASIC HFIs in this OS */
struct hfi1_asic_data *asic_data;
- /* hfi1_pportdata, points to array of (physical) port-specific
- * data structs, indexed by pidx (0..n-1)
- */
- struct hfi1_pportdata *pport;
-
/* mem-mapped pointer to base of PIO buffers */
void __iomem *piobase;
/*
@@ -896,20 +900,13 @@ struct hfi1_devdata {
/* send context numbers and sizes for each type */
struct sc_config_sizes sc_sizes[SC_MAX];
- u32 lcb_access_count; /* count of LCB users */
-
char *boardname; /* human readable board info */
- /* device (not port) flags, basically device capabilities */
- u32 flags;
-
/* reset value */
u64 z_int_counter;
u64 z_rcv_limit;
u64 z_send_schedule;
- /* percpu int_counter */
- u64 __percpu *int_counter;
- u64 __percpu *rcv_limit;
+
u64 __percpu *send_schedule;
/* number of receive contexts in use by the driver */
u32 num_rcv_contexts;
@@ -924,6 +921,7 @@ struct hfi1_devdata {
/* base receive interrupt timeout, in CSR units */
u32 rcv_intr_timeout_csr;
+ u32 freezelen; /* max length of freezemsg */
u64 __iomem *egrtidbase;
spinlock_t sendctrl_lock; /* protect changes to SendCtrl */
spinlock_t rcvctrl_lock; /* protect changes to RcvCtrl */
@@ -945,7 +943,6 @@ struct hfi1_devdata {
* IB link status cheaply
*/
struct hfi1_status *status;
- u32 freezelen; /* max length of freezemsg */
/* revision register shadow */
u64 revision;
@@ -973,6 +970,8 @@ struct hfi1_devdata {
u16 rcvegrbufsize_shift;
/* both sides of the PCIe link are gen3 capable */
u8 link_gen3_capable;
+ /* default link down value (poll/sleep) */
+ u8 link_default;
/* localbus width (1, 2,4,8,16,32) from config space */
u32 lbus_width;
/* localbus speed in MHz */
@@ -1008,8 +1007,6 @@ struct hfi1_devdata {
u8 hfi1_id;
/* implementation code */
u8 icode;
- /* default link down value (poll/sleep) */
- u8 link_default;
/* vAU of this device */
u8 vau;
/* vCU of this device */
@@ -1020,27 +1017,17 @@ struct hfi1_devdata {
u16 vl15_init;
/* Misc small ints */
- /* Number of physical ports available */
- u8 num_pports;
- /* Lowest context number which can be used by user processes */
- u8 first_user_ctxt;
u8 n_krcv_queues;
u8 qos_shift;
- u8 qpn_mask;
- u16 rhf_offset; /* offset of RHF within receive header entry */
u16 irev; /* implementation revision */
u16 dc8051_ver; /* 8051 firmware version */
+ spinlock_t hfi1_diag_trans_lock; /* protect diag observer ops */
struct platform_config platform_config;
struct platform_config_cache pcfg_cache;
struct diag_client *diag_client;
- spinlock_t hfi1_diag_trans_lock; /* protect diag observer ops */
-
- u8 psxmitwait_supported;
- /* cycle length of PS* counters in HW (in picoseconds) */
- u16 psxmitwait_check_rate;
/* MSI-X information */
struct hfi1_msix_entry *msix_entries;
@@ -1055,6 +1042,9 @@ struct hfi1_devdata {
struct rcv_array_data rcv_entries;
+ /* cycle length of PS* counters in HW (in picoseconds) */
+ u16 psxmitwait_check_rate;
+
/*
* 64 bit synthetic counters
*/
@@ -1085,11 +1075,11 @@ struct hfi1_devdata {
struct err_info_rcvport err_info_rcvport;
struct err_info_constraint err_info_rcv_constraint;
struct err_info_constraint err_info_xmit_constraint;
- u8 err_info_uncorrectable;
- u8 err_info_fmconfig;
atomic_t drop_packet;
u8 do_drop;
+ u8 err_info_uncorrectable;
+ u8 err_info_fmconfig;
/*
* Software counters for the status bits defined by the
@@ -1112,40 +1102,60 @@ struct hfi1_devdata {
u64 sw_cce_err_status_aggregate;
/* Software counter that aggregates all bypass packet rcv errors */
u64 sw_rcv_bypass_packet_errors;
- /* receive interrupt functions */
- rhf_rcv_function_ptr *rhf_rcv_function_map;
+ /* receive interrupt function */
rhf_rcv_function_ptr normal_rhf_rcv_functions[8];
+ /* Save the enabled LCB error bits */
+ u64 lcb_err_en;
+
/*
* Capability to have different send engines simply by changing a
* pointer value.
*/
- send_routine process_pio_send;
+ send_routine process_pio_send ____cacheline_aligned_in_smp;
send_routine process_dma_send;
void (*pio_inline_send)(struct hfi1_devdata *dd, struct pio_buf *pbuf,
u64 pbc, const void *from, size_t count);
+ /* hfi1_pportdata, points to array of (physical) port-specific
+ * data structs, indexed by pidx (0..n-1)
+ */
+ struct hfi1_pportdata *pport;
+ /* receive context data */
+ struct hfi1_ctxtdata **rcd;
+ u64 __percpu *int_counter;
+ /* device (not port) flags, basically device capabilities */
+ u16 flags;
+ /* Number of physical ports available */
+ u8 num_pports;
+ /* Lowest context number which can be used by user processes */
+ u8 first_user_ctxt;
+ /* adding a new field here would make it part of this cacheline */
+
+ /* seqlock for sc2vl */
+ seqlock_t sc2vl_lock ____cacheline_aligned_in_smp;
+ u64 sc2vl[4];
+ /* receive interrupt functions */
+ rhf_rcv_function_ptr *rhf_rcv_function_map;
+ u64 __percpu *rcv_limit;
+ u16 rhf_offset; /* offset of RHF within receive header entry */
+ /* adding a new field here would make it part of this cacheline */
/* OUI comes from the HW. Used everywhere as 3 separate bytes. */
u8 oui1;
u8 oui2;
u8 oui3;
+ u8 dc_shutdown;
+
/* Timer and counter used to detect RcvBufOvflCnt changes */
struct timer_list rcverr_timer;
- u32 rcv_ovfl_cnt;
wait_queue_head_t event_queue;
- /* Save the enabled LCB error bits */
- u64 lcb_err_en;
- u8 dc_shutdown;
-
/* receive context tail dummy address */
__le64 *rcvhdrtail_dummy_kvaddr;
dma_addr_t rcvhdrtail_dummy_dma;
- bool eprom_available; /* true if EPROM is available for this device */
- bool aspm_supported; /* Does HW support ASPM */
- bool aspm_enabled; /* ASPM state: enabled/disabled */
+ u32 rcv_ovfl_cnt;
/* Serialize ASPM enable/disable between multiple verbs contexts */
spinlock_t aspm_lock;
/* Number of verbs contexts which have disabled ASPM */
@@ -1155,8 +1165,11 @@ struct hfi1_devdata {
/* Used to wait for outstanding user space clients before dev removal */
struct completion user_comp;
- struct hfi1_affinity *affinity;
+ bool eprom_available; /* true if EPROM is available for this device */
+ bool aspm_supported; /* Does HW support ASPM */
+ bool aspm_enabled; /* ASPM state: enabled/disabled */
struct rhashtable sdma_rht;
+
struct kobject kobj;
};
@@ -1604,6 +1617,17 @@ static inline u16 hfi1_get_pkey(struct hfi1_ibport *ibp, unsigned index)
}
/*
+ * Return the indexed GUID from the port GUIDs table.
+ */
+static inline __be64 get_sguid(struct hfi1_ibport *ibp, unsigned int index)
+{
+ struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+
+ WARN_ON(index >= HFI1_GUIDS_PER_PORT);
+ return cpu_to_be64(ppd->guids[index]);
+}
+
+/*
* Called by readers of cc_state only, must call under rcu_read_lock().
*/
static inline struct cc_state *get_cc_state(struct hfi1_pportdata *ppd)
@@ -1982,6 +2006,12 @@ static inline u32 qsfp_resource(struct hfi1_devdata *dd)
return i2c_target(dd->hfi1_id);
}
+/* Is this device integrated or discrete? */
+static inline bool is_integrated(struct hfi1_devdata *dd)
+{
+ return dd->pcidev->device == PCI_DEVICE_ID_INTEL1;
+}
+
int hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp);
#define DD_DEV_ENTRY(dd) __string(dev, dev_name(&(dd)->pcidev->dev))
diff --git a/drivers/infiniband/hw/hfi1/iowait.h b/drivers/infiniband/hw/hfi1/iowait.h
index 2ec6ef38d389..d9740ddea6f1 100644
--- a/drivers/infiniband/hw/hfi1/iowait.h
+++ b/drivers/infiniband/hw/hfi1/iowait.h
@@ -64,6 +64,7 @@ struct sdma_engine;
/**
* struct iowait - linkage for delayed progress/waiting
* @list: used to add/insert into QP/PQ wait lists
+ * @lock: uses to record the list head lock
* @tx_head: overflow list of sdma_txreq's
* @sleep: no space callback
* @wakeup: space callback wakeup
@@ -91,6 +92,11 @@ struct sdma_engine;
* so sleeping is not allowed.
*
* The wait_dma member along with the iow
+ *
+ * The lock field is used by waiters to record
+ * the seqlock_t that guards the list head.
+ * Waiters explicity know that, but the destroy
+ * code that unwaits QPs does not.
*/
struct iowait {
@@ -103,6 +109,7 @@ struct iowait {
unsigned seq);
void (*wakeup)(struct iowait *wait, int reason);
void (*sdma_drained)(struct iowait *wait);
+ seqlock_t *lock;
struct work_struct iowork;
wait_queue_head_t wait_dma;
wait_queue_head_t wait_pio;
@@ -141,6 +148,7 @@ static inline void iowait_init(
void (*sdma_drained)(struct iowait *wait))
{
wait->count = 0;
+ wait->lock = NULL;
INIT_LIST_HEAD(&wait->list);
INIT_LIST_HEAD(&wait->tx_head);
INIT_WORK(&wait->iowork, func);
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c
index 9487c9bb8920..6e595afca24c 100644
--- a/drivers/infiniband/hw/hfi1/mad.c
+++ b/drivers/infiniband/hw/hfi1/mad.c
@@ -128,7 +128,7 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
smp = send_buf->mad;
smp->base_version = OPA_MGMT_BASE_VERSION;
smp->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
- smp->class_version = OPA_SMI_CLASS_VERSION;
+ smp->class_version = OPA_SM_CLASS_VERSION;
smp->method = IB_MGMT_METHOD_TRAP;
ibp->rvp.tid++;
smp->tid = cpu_to_be64(ibp->rvp.tid);
@@ -336,20 +336,20 @@ static int __subn_get_opa_nodeinfo(struct opa_smp *smp, u32 am, u8 *data,
ni = (struct opa_node_info *)data;
/* GUID 0 is illegal */
- if (am || pidx >= dd->num_pports || dd->pport[pidx].guid == 0) {
+ if (am || pidx >= dd->num_pports || ibdev->node_guid == 0 ||
+ get_sguid(to_iport(ibdev, port), HFI1_PORT_GUID_INDEX) == 0) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}
- ni->port_guid = cpu_to_be64(dd->pport[pidx].guid);
+ ni->port_guid = get_sguid(to_iport(ibdev, port), HFI1_PORT_GUID_INDEX);
ni->base_version = OPA_MGMT_BASE_VERSION;
- ni->class_version = OPA_SMI_CLASS_VERSION;
+ ni->class_version = OPA_SM_CLASS_VERSION;
ni->node_type = 1; /* channel adapter */
ni->num_ports = ibdev->phys_port_cnt;
/* This is already in network order */
ni->system_image_guid = ib_hfi1_sys_image_guid;
- /* Use first-port GUID as node */
- ni->node_guid = cpu_to_be64(dd->pport->guid);
+ ni->node_guid = ibdev->node_guid;
ni->partition_cap = cpu_to_be16(hfi1_get_npkeys(dd));
ni->device_id = cpu_to_be16(dd->pcidev->device);
ni->revision = cpu_to_be32(dd->minrev);
@@ -373,19 +373,20 @@ static int subn_get_nodeinfo(struct ib_smp *smp, struct ib_device *ibdev,
/* GUID 0 is illegal */
if (smp->attr_mod || pidx >= dd->num_pports ||
- dd->pport[pidx].guid == 0)
+ ibdev->node_guid == 0 ||
+ get_sguid(to_iport(ibdev, port), HFI1_PORT_GUID_INDEX) == 0) {
smp->status |= IB_SMP_INVALID_FIELD;
- else
- nip->port_guid = cpu_to_be64(dd->pport[pidx].guid);
+ return reply((struct ib_mad_hdr *)smp);
+ }
+ nip->port_guid = get_sguid(to_iport(ibdev, port), HFI1_PORT_GUID_INDEX);
nip->base_version = OPA_MGMT_BASE_VERSION;
- nip->class_version = OPA_SMI_CLASS_VERSION;
+ nip->class_version = OPA_SM_CLASS_VERSION;
nip->node_type = 1; /* channel adapter */
nip->num_ports = ibdev->phys_port_cnt;
/* This is already in network order */
nip->sys_guid = ib_hfi1_sys_image_guid;
- /* Use first-port GUID as node */
- nip->node_guid = cpu_to_be64(dd->pport->guid);
+ nip->node_guid = ibdev->node_guid;
nip->partition_cap = cpu_to_be16(hfi1_get_npkeys(dd));
nip->device_id = cpu_to_be16(dd->pcidev->device);
nip->revision = cpu_to_be32(dd->minrev);
@@ -2302,7 +2303,7 @@ static int pma_get_opa_classportinfo(struct opa_pma_mad *pmp,
pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD;
p->base_version = OPA_MGMT_BASE_VERSION;
- p->class_version = OPA_SMI_CLASS_VERSION;
+ p->class_version = OPA_SM_CLASS_VERSION;
/*
* Expected response time is 4.096 usec. * 2^18 == 1.073741824 sec.
*/
@@ -4022,7 +4023,7 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,
am = be32_to_cpu(smp->attr_mod);
attr_id = smp->attr_id;
- if (smp->class_version != OPA_SMI_CLASS_VERSION) {
+ if (smp->class_version != OPA_SM_CLASS_VERSION) {
smp->status |= IB_SMP_UNSUP_VERSION;
ret = reply((struct ib_mad_hdr *)smp);
return ret;
@@ -4232,7 +4233,7 @@ static int process_perf_opa(struct ib_device *ibdev, u8 port,
*out_mad = *in_mad;
- if (pmp->mad_hdr.class_version != OPA_SMI_CLASS_VERSION) {
+ if (pmp->mad_hdr.class_version != OPA_SM_CLASS_VERSION) {
pmp->mad_hdr.status |= IB_SMP_UNSUP_VERSION;
return reply((struct ib_mad_hdr *)pmp);
}
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
index 7ad30898fc19..ccbf52c8ff6f 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -81,7 +81,7 @@ static void do_remove(struct mmu_rb_handler *handler,
struct list_head *del_list);
static void handle_remove(struct work_struct *work);
-static struct mmu_notifier_ops mn_opts = {
+static const struct mmu_notifier_ops mn_opts = {
.invalidate_page = mmu_notifier_page,
.invalidate_range_start = mmu_notifier_range_start,
};
diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c
index d89b8745d4c1..615be68e40b3 100644
--- a/drivers/infiniband/hw/hfi1/pio.c
+++ b/drivers/infiniband/hw/hfi1/pio.c
@@ -758,6 +758,7 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
sc->hw_context = hw_context;
cr_group_addresses(sc, &dma);
sc->credits = sci->credits;
+ sc->size = sc->credits * PIO_BLOCK_SIZE;
/* PIO Send Memory Address details */
#define PIO_ADDR_CONTEXT_MASK 0xfful
@@ -1242,6 +1243,7 @@ int sc_enable(struct send_context *sc)
sc->free = 0;
sc->alloc_free = 0;
sc->fill = 0;
+ sc->fill_wrap = 0;
sc->sr_head = 0;
sc->sr_tail = 0;
sc->flags = 0;
@@ -1385,7 +1387,7 @@ struct pio_buf *sc_buffer_alloc(struct send_context *sc, u32 dw_len,
unsigned long flags;
unsigned long avail;
unsigned long blocks = dwords_to_blocks(dw_len);
- unsigned long start_fill;
+ u32 fill_wrap;
int trycount = 0;
u32 head, next;
@@ -1410,9 +1412,7 @@ retry:
(sc->fill - sc->alloc_free);
if (blocks > avail) {
/* still no room, actively update */
- spin_unlock_irqrestore(&sc->alloc_lock, flags);
sc_release_update(sc);
- spin_lock_irqsave(&sc->alloc_lock, flags);
sc->alloc_free = ACCESS_ONCE(sc->free);
trycount++;
goto retry;
@@ -1428,8 +1428,11 @@ retry:
head = sc->sr_head;
/* "allocate" the buffer */
- start_fill = sc->fill;
sc->fill += blocks;
+ fill_wrap = sc->fill_wrap;
+ sc->fill_wrap += blocks;
+ if (sc->fill_wrap >= sc->credits)
+ sc->fill_wrap = sc->fill_wrap - sc->credits;
/*
* Fill the parts that the releaser looks at before moving the head.
@@ -1458,11 +1461,8 @@ retry:
spin_unlock_irqrestore(&sc->alloc_lock, flags);
/* finish filling in the buffer outside the lock */
- pbuf->start = sc->base_addr + ((start_fill % sc->credits)
- * PIO_BLOCK_SIZE);
- pbuf->size = sc->credits * PIO_BLOCK_SIZE;
- pbuf->end = sc->base_addr + pbuf->size;
- pbuf->block_count = blocks;
+ pbuf->start = sc->base_addr + fill_wrap * PIO_BLOCK_SIZE;
+ pbuf->end = sc->base_addr + sc->size;
pbuf->qw_written = 0;
pbuf->carry_bytes = 0;
pbuf->carry.val64 = 0;
@@ -1573,6 +1573,7 @@ static void sc_piobufavail(struct send_context *sc)
qp = iowait_to_qp(wait);
priv = qp->priv;
list_del_init(&priv->s_iowait.list);
+ priv->s_iowait.lock = NULL;
/* refcount held until actual wake up */
qps[n++] = qp;
}
@@ -2028,29 +2029,17 @@ freesc15:
int init_credit_return(struct hfi1_devdata *dd)
{
int ret;
- int num_numa;
int i;
- num_numa = num_online_nodes();
- /* enforce the expectation that the numas are compact */
- for (i = 0; i < num_numa; i++) {
- if (!node_online(i)) {
- dd_dev_err(dd, "NUMA nodes are not compact\n");
- ret = -EINVAL;
- goto done;
- }
- }
-
dd->cr_base = kcalloc(
- num_numa,
+ node_affinity.num_possible_nodes,
sizeof(struct credit_return_base),
GFP_KERNEL);
if (!dd->cr_base) {
- dd_dev_err(dd, "Unable to allocate credit return base\n");
ret = -ENOMEM;
goto done;
}
- for (i = 0; i < num_numa; i++) {
+ for_each_node_with_cpus(i) {
int bytes = TXE_NUM_CONTEXTS * sizeof(struct credit_return);
set_dev_node(&dd->pcidev->dev, i);
@@ -2077,14 +2066,11 @@ done:
void free_credit_return(struct hfi1_devdata *dd)
{
- int num_numa;
int i;
if (!dd->cr_base)
return;
-
- num_numa = num_online_nodes();
- for (i = 0; i < num_numa; i++) {
+ for (i = 0; i < node_affinity.num_possible_nodes; i++) {
if (dd->cr_base[i].va) {
dma_free_coherent(&dd->pcidev->dev,
TXE_NUM_CONTEXTS *
diff --git a/drivers/infiniband/hw/hfi1/pio.h b/drivers/infiniband/hw/hfi1/pio.h
index e709eaf743b5..867e5ffc3595 100644
--- a/drivers/infiniband/hw/hfi1/pio.h
+++ b/drivers/infiniband/hw/hfi1/pio.h
@@ -83,53 +83,55 @@ struct pio_buf {
void *arg; /* argument for cb */
void __iomem *start; /* buffer start address */
void __iomem *end; /* context end address */
- unsigned long size; /* context size, in bytes */
unsigned long sent_at; /* buffer is sent when <= free */
- u32 block_count; /* size of buffer, in blocks */
- u32 qw_written; /* QW written so far */
- u32 carry_bytes; /* number of valid bytes in carry */
union mix carry; /* pending unwritten bytes */
+ u16 qw_written; /* QW written so far */
+ u8 carry_bytes; /* number of valid bytes in carry */
};
/* cache line aligned pio buffer array */
union pio_shadow_ring {
struct pio_buf pbuf;
- u64 unused[16]; /* cache line spacer */
} ____cacheline_aligned;
/* per-NUMA send context */
struct send_context {
/* read-only after init */
struct hfi1_devdata *dd; /* device */
- void __iomem *base_addr; /* start of PIO memory */
union pio_shadow_ring *sr; /* shadow ring */
+ void __iomem *base_addr; /* start of PIO memory */
+ u32 __percpu *buffers_allocated;/* count of buffers allocated */
+ u32 size; /* context size, in bytes */
- volatile __le64 *hw_free; /* HW free counter */
- struct work_struct halt_work; /* halted context work queue entry */
- unsigned long flags; /* flags */
int node; /* context home node */
- int type; /* context type */
- u32 sw_index; /* software index number */
- u32 hw_context; /* hardware context number */
- u32 credits; /* number of blocks in context */
u32 sr_size; /* size of the shadow ring */
- u32 group; /* credit return group */
+ u16 flags; /* flags */
+ u8 type; /* context type */
+ u8 sw_index; /* software index number */
+ u8 hw_context; /* hardware context number */
+ u8 group; /* credit return group */
+
/* allocator fields */
spinlock_t alloc_lock ____cacheline_aligned_in_smp;
+ u32 sr_head; /* shadow ring head */
unsigned long fill; /* official alloc count */
unsigned long alloc_free; /* copy of free (less cache thrash) */
- u32 sr_head; /* shadow ring head */
+ u32 fill_wrap; /* tracks fill within ring */
+ u32 credits; /* number of blocks in context */
+ /* adding a new field here would make it part of this cacheline */
+
/* releaser fields */
spinlock_t release_lock ____cacheline_aligned_in_smp;
- unsigned long free; /* official free count */
u32 sr_tail; /* shadow ring tail */
+ unsigned long free; /* official free count */
+ volatile __le64 *hw_free; /* HW free counter */
/* list for PIO waiters */
struct list_head piowait ____cacheline_aligned_in_smp;
spinlock_t credit_ctrl_lock ____cacheline_aligned_in_smp;
- u64 credit_ctrl; /* cache for credit control */
u32 credit_intr_count; /* count of credit intr users */
- u32 __percpu *buffers_allocated;/* count of buffers allocated */
+ u64 credit_ctrl; /* cache for credit control */
wait_queue_head_t halt_wait; /* wait until kernel sees interrupt */
+ struct work_struct halt_work; /* halted context work queue entry */
};
/* send context flags */
diff --git a/drivers/infiniband/hw/hfi1/pio_copy.c b/drivers/infiniband/hw/hfi1/pio_copy.c
index aa7773643107..03024cec78dd 100644
--- a/drivers/infiniband/hw/hfi1/pio_copy.c
+++ b/drivers/infiniband/hw/hfi1/pio_copy.c
@@ -129,8 +129,8 @@ void pio_copy(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc,
dest += sizeof(u64);
}
- dest -= pbuf->size;
- dend -= pbuf->size;
+ dest -= pbuf->sc->size;
+ dend -= pbuf->sc->size;
}
/* write 8-byte non-SOP, non-wrap chunk data */
@@ -361,8 +361,8 @@ void seg_pio_copy_start(struct pio_buf *pbuf, u64 pbc,
dest += sizeof(u64);
}
- dest -= pbuf->size;
- dend -= pbuf->size;
+ dest -= pbuf->sc->size;
+ dend -= pbuf->sc->size;
}
/* write 8-byte non-SOP, non-wrap chunk data */
@@ -458,8 +458,8 @@ static void mid_copy_mix(struct pio_buf *pbuf, const void *from, size_t nbytes)
dest += sizeof(u64);
}
- dest -= pbuf->size;
- dend -= pbuf->size;
+ dest -= pbuf->sc->size;
+ dend -= pbuf->sc->size;
}
/* write 8-byte non-SOP, non-wrap chunk data */
@@ -492,7 +492,7 @@ static void mid_copy_mix(struct pio_buf *pbuf, const void *from, size_t nbytes)
*/
/* adjust if we have wrapped */
if (dest >= pbuf->end)
- dest -= pbuf->size;
+ dest -= pbuf->sc->size;
/* jump to the SOP range if within the first block */
else if (pbuf->qw_written < PIO_BLOCK_QWS)
dest += SOP_DISTANCE;
@@ -584,8 +584,8 @@ static void mid_copy_straight(struct pio_buf *pbuf,
dest += sizeof(u64);
}
- dest -= pbuf->size;
- dend -= pbuf->size;
+ dest -= pbuf->sc->size;
+ dend -= pbuf->sc->size;
}
/* write 8-byte non-SOP, non-wrap chunk data */
@@ -666,7 +666,7 @@ void seg_pio_copy_mid(struct pio_buf *pbuf, const void *from, size_t nbytes)
*/
/* adjust if we've wrapped */
if (dest >= pbuf->end)
- dest -= pbuf->size;
+ dest -= pbuf->sc->size;
/* jump to SOP range if within the first block */
else if (pbuf->qw_written < PIO_BLOCK_QWS)
dest += SOP_DISTANCE;
@@ -719,7 +719,7 @@ void seg_pio_copy_end(struct pio_buf *pbuf)
*/
/* adjust if we have wrapped */
if (dest >= pbuf->end)
- dest -= pbuf->size;
+ dest -= pbuf->sc->size;
/* jump to the SOP range if within the first block */
else if (pbuf->qw_written < PIO_BLOCK_QWS)
dest += SOP_DISTANCE;
diff --git a/drivers/infiniband/hw/hfi1/platform.c b/drivers/infiniband/hw/hfi1/platform.c
index 202433178864..838fe84e285a 100644
--- a/drivers/infiniband/hw/hfi1/platform.c
+++ b/drivers/infiniband/hw/hfi1/platform.c
@@ -49,6 +49,90 @@
#include "efivar.h"
#include "eprom.h"
+static int validate_scratch_checksum(struct hfi1_devdata *dd)
+{
+ u64 checksum = 0, temp_scratch = 0;
+ int i, j, version;
+
+ temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH);
+ version = (temp_scratch & BITMAP_VERSION_SMASK) >> BITMAP_VERSION_SHIFT;
+
+ /* Prevent power on default of all zeroes from passing checksum */
+ if (!version)
+ return 0;
+
+ /*
+ * ASIC scratch 0 only contains the checksum and bitmap version as
+ * fields of interest, both of which are handled separately from the
+ * loop below, so skip it
+ */
+ checksum += version;
+ for (i = 1; i < ASIC_NUM_SCRATCH; i++) {
+ temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH + (8 * i));
+ for (j = sizeof(u64); j != 0; j -= 2) {
+ checksum += (temp_scratch & 0xFFFF);
+ temp_scratch >>= 16;
+ }
+ }
+
+ while (checksum >> 16)
+ checksum = (checksum & CHECKSUM_MASK) + (checksum >> 16);
+
+ temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH);
+ temp_scratch &= CHECKSUM_SMASK;
+ temp_scratch >>= CHECKSUM_SHIFT;
+
+ if (checksum + temp_scratch == 0xFFFF)
+ return 1;
+ return 0;
+}
+
+static void save_platform_config_fields(struct hfi1_devdata *dd)
+{
+ struct hfi1_pportdata *ppd = dd->pport;
+ u64 temp_scratch = 0, temp_dest = 0;
+
+ temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH_1);
+
+ temp_dest = temp_scratch &
+ (dd->hfi1_id ? PORT1_PORT_TYPE_SMASK :
+ PORT0_PORT_TYPE_SMASK);
+ ppd->port_type = temp_dest >>
+ (dd->hfi1_id ? PORT1_PORT_TYPE_SHIFT :
+ PORT0_PORT_TYPE_SHIFT);
+
+ temp_dest = temp_scratch &
+ (dd->hfi1_id ? PORT1_LOCAL_ATTEN_SMASK :
+ PORT0_LOCAL_ATTEN_SMASK);
+ ppd->local_atten = temp_dest >>
+ (dd->hfi1_id ? PORT1_LOCAL_ATTEN_SHIFT :
+ PORT0_LOCAL_ATTEN_SHIFT);
+
+ temp_dest = temp_scratch &
+ (dd->hfi1_id ? PORT1_REMOTE_ATTEN_SMASK :
+ PORT0_REMOTE_ATTEN_SMASK);
+ ppd->remote_atten = temp_dest >>
+ (dd->hfi1_id ? PORT1_REMOTE_ATTEN_SHIFT :
+ PORT0_REMOTE_ATTEN_SHIFT);
+
+ temp_dest = temp_scratch &
+ (dd->hfi1_id ? PORT1_DEFAULT_ATTEN_SMASK :
+ PORT0_DEFAULT_ATTEN_SMASK);
+ ppd->default_atten = temp_dest >>
+ (dd->hfi1_id ? PORT1_DEFAULT_ATTEN_SHIFT :
+ PORT0_DEFAULT_ATTEN_SHIFT);
+
+ temp_scratch = read_csr(dd, dd->hfi1_id ? ASIC_CFG_SCRATCH_3 :
+ ASIC_CFG_SCRATCH_2);
+
+ ppd->tx_preset_eq = (temp_scratch & TX_EQ_SMASK) >> TX_EQ_SHIFT;
+ ppd->tx_preset_noeq = (temp_scratch & TX_NO_EQ_SMASK) >> TX_NO_EQ_SHIFT;
+ ppd->rx_preset = (temp_scratch & RX_SMASK) >> RX_SHIFT;
+
+ ppd->max_power_class = (temp_scratch & QSFP_MAX_POWER_SMASK) >>
+ QSFP_MAX_POWER_SHIFT;
+}
+
void get_platform_config(struct hfi1_devdata *dd)
{
int ret = 0;
@@ -56,38 +140,49 @@ void get_platform_config(struct hfi1_devdata *dd)
u8 *temp_platform_config = NULL;
u32 esize;
- ret = eprom_read_platform_config(dd, (void **)&temp_platform_config,
- &esize);
- if (!ret) {
- /* success */
- size = esize;
- goto success;
+ if (is_integrated(dd)) {
+ if (validate_scratch_checksum(dd)) {
+ save_platform_config_fields(dd);
+ return;
+ }
+ dd_dev_err(dd, "%s: Config bitmap corrupted/uninitialized\n",
+ __func__);
+ dd_dev_err(dd,
+ "%s: Please update your BIOS to support active channels\n",
+ __func__);
+ } else {
+ ret = eprom_read_platform_config(dd,
+ (void **)&temp_platform_config,
+ &esize);
+ if (!ret) {
+ /* success */
+ dd->platform_config.data = temp_platform_config;
+ dd->platform_config.size = esize;
+ return;
+ }
+ /* fail, try EFI variable */
+
+ ret = read_hfi1_efi_var(dd, "configuration", &size,
+ (void **)&temp_platform_config);
+ if (!ret) {
+ dd->platform_config.data = temp_platform_config;
+ dd->platform_config.size = size;
+ return;
+ }
}
- /* fail, try EFI variable */
-
- ret = read_hfi1_efi_var(dd, "configuration", &size,
- (void **)&temp_platform_config);
- if (!ret)
- goto success;
-
- dd_dev_info(dd,
- "%s: Failed to get platform config from UEFI, falling back to request firmware\n",
- __func__);
+ dd_dev_err(dd,
+ "%s: Failed to get platform config, falling back to sub-optimal default file\n",
+ __func__);
/* fall back to request firmware */
platform_config_load = 1;
- return;
-
-success:
- dd->platform_config.data = temp_platform_config;
- dd->platform_config.size = size;
}
void free_platform_config(struct hfi1_devdata *dd)
{
if (!platform_config_load) {
/*
- * was loaded from EFI, release memory
- * allocated by read_efi_var
+ * was loaded from EFI or the EPROM, release memory
+ * allocated by read_efi_var/eprom_read_platform_config
*/
kfree(dd->platform_config.data);
}
@@ -100,12 +195,16 @@ void free_platform_config(struct hfi1_devdata *dd)
void get_port_type(struct hfi1_pportdata *ppd)
{
int ret;
+ u32 temp;
ret = get_platform_config_field(ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
- PORT_TABLE_PORT_TYPE, &ppd->port_type,
+ PORT_TABLE_PORT_TYPE, &temp,
4);
- if (ret)
+ if (ret) {
ppd->port_type = PORT_TYPE_UNKNOWN;
+ return;
+ }
+ ppd->port_type = temp;
}
int set_qsfp_tx(struct hfi1_pportdata *ppd, int on)
@@ -538,6 +637,38 @@ static void apply_tx_lanes(struct hfi1_pportdata *ppd, u8 field_id,
}
}
+/*
+ * Return a special SerDes setting for low power AOC cables. The power class
+ * threshold and setting being used were all found by empirical testing.
+ *
+ * Summary of the logic:
+ *
+ * if (QSFP and QSFP_TYPE == AOC and QSFP_POWER_CLASS < 4)
+ * return 0xe
+ * return 0; // leave at default
+ */
+static u8 aoc_low_power_setting(struct hfi1_pportdata *ppd)
+{
+ u8 *cache = ppd->qsfp_info.cache;
+ int power_class;
+
+ /* QSFP only */
+ if (ppd->port_type != PORT_TYPE_QSFP)
+ return 0; /* leave at default */
+
+ /* active optical cables only */
+ switch ((cache[QSFP_MOD_TECH_OFFS] & 0xF0) >> 4) {
+ case 0x0 ... 0x9: /* fallthrough */
+ case 0xC: /* fallthrough */
+ case 0xE:
+ /* active AOC */
+ power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);
+ if (power_class < QSFP_POWER_CLASS_4)
+ return 0xe;
+ }
+ return 0; /* leave at default */
+}
+
static void apply_tunings(
struct hfi1_pportdata *ppd, u32 tx_preset_index,
u8 tuning_method, u32 total_atten, u8 limiting_active)
@@ -606,7 +737,17 @@ static void apply_tunings(
tx_preset_index, TX_PRESET_TABLE_POSTCUR, &tx_preset, 4);
postcur = tx_preset;
- config_data = precur | (attn << 8) | (postcur << 16);
+ /*
+ * NOTES:
+ * o The aoc_low_power_setting is applied to all lanes even
+ * though only lane 0's value is examined by the firmware.
+ * o A lingering low power setting after a cable swap does
+ * not occur. On cable unplug the 8051 is reset and
+ * restarted on cable insert. This resets all settings to
+ * their default, erasing any previous low power setting.
+ */
+ config_data = precur | (attn << 8) | (postcur << 16) |
+ (aoc_low_power_setting(ppd) << 24);
apply_tx_lanes(ppd, TX_EQ_SETTINGS, config_data,
"Applying TX settings");
diff --git a/drivers/infiniband/hw/hfi1/platform.h b/drivers/infiniband/hw/hfi1/platform.h
index e2c21613c326..eed0aa9124fa 100644
--- a/drivers/infiniband/hw/hfi1/platform.h
+++ b/drivers/infiniband/hw/hfi1/platform.h
@@ -168,16 +168,6 @@ struct platform_config_cache {
struct platform_config_data config_tables[PLATFORM_CONFIG_TABLE_MAX];
};
-static const u32 platform_config_table_limits[PLATFORM_CONFIG_TABLE_MAX] = {
- 0,
- SYSTEM_TABLE_MAX,
- PORT_TABLE_MAX,
- RX_PRESET_TABLE_MAX,
- TX_PRESET_TABLE_MAX,
- QSFP_ATTEN_TABLE_MAX,
- VARIABLE_SETTINGS_TABLE_MAX
-};
-
/* This section defines default values and encodings for the
* fields defined for each table above
*/
@@ -295,6 +285,123 @@ enum link_tuning_encoding {
OPA_UNKNOWN_TUNING
};
+/*
+ * Shifts and masks for the link SI tuning values stuffed into the ASIC scratch
+ * registers for integrated platforms
+ */
+#define PORT0_PORT_TYPE_SHIFT 0
+#define PORT0_LOCAL_ATTEN_SHIFT 4
+#define PORT0_REMOTE_ATTEN_SHIFT 10
+#define PORT0_DEFAULT_ATTEN_SHIFT 32
+
+#define PORT1_PORT_TYPE_SHIFT 16
+#define PORT1_LOCAL_ATTEN_SHIFT 20
+#define PORT1_REMOTE_ATTEN_SHIFT 26
+#define PORT1_DEFAULT_ATTEN_SHIFT 40
+
+#define PORT0_PORT_TYPE_MASK 0xFUL
+#define PORT0_LOCAL_ATTEN_MASK 0x3FUL
+#define PORT0_REMOTE_ATTEN_MASK 0x3FUL
+#define PORT0_DEFAULT_ATTEN_MASK 0xFFUL
+
+#define PORT1_PORT_TYPE_MASK 0xFUL
+#define PORT1_LOCAL_ATTEN_MASK 0x3FUL
+#define PORT1_REMOTE_ATTEN_MASK 0x3FUL
+#define PORT1_DEFAULT_ATTEN_MASK 0xFFUL
+
+#define PORT0_PORT_TYPE_SMASK (PORT0_PORT_TYPE_MASK << \
+ PORT0_PORT_TYPE_SHIFT)
+#define PORT0_LOCAL_ATTEN_SMASK (PORT0_LOCAL_ATTEN_MASK << \
+ PORT0_LOCAL_ATTEN_SHIFT)
+#define PORT0_REMOTE_ATTEN_SMASK (PORT0_REMOTE_ATTEN_MASK << \
+ PORT0_REMOTE_ATTEN_SHIFT)
+#define PORT0_DEFAULT_ATTEN_SMASK (PORT0_DEFAULT_ATTEN_MASK << \
+ PORT0_DEFAULT_ATTEN_SHIFT)
+
+#define PORT1_PORT_TYPE_SMASK (PORT1_PORT_TYPE_MASK << \
+ PORT1_PORT_TYPE_SHIFT)
+#define PORT1_LOCAL_ATTEN_SMASK (PORT1_LOCAL_ATTEN_MASK << \
+ PORT1_LOCAL_ATTEN_SHIFT)
+#define PORT1_REMOTE_ATTEN_SMASK (PORT1_REMOTE_ATTEN_MASK << \
+ PORT1_REMOTE_ATTEN_SHIFT)
+#define PORT1_DEFAULT_ATTEN_SMASK (PORT1_DEFAULT_ATTEN_MASK << \
+ PORT1_DEFAULT_ATTEN_SHIFT)
+
+#define QSFP_MAX_POWER_SHIFT 0
+#define TX_NO_EQ_SHIFT 4
+#define TX_EQ_SHIFT 25
+#define RX_SHIFT 46
+
+#define QSFP_MAX_POWER_MASK 0xFUL
+#define TX_NO_EQ_MASK 0x1FFFFFUL
+#define TX_EQ_MASK 0x1FFFFFUL
+#define RX_MASK 0xFFFFUL
+
+#define QSFP_MAX_POWER_SMASK (QSFP_MAX_POWER_MASK << \
+ QSFP_MAX_POWER_SHIFT)
+#define TX_NO_EQ_SMASK (TX_NO_EQ_MASK << TX_NO_EQ_SHIFT)
+#define TX_EQ_SMASK (TX_EQ_MASK << TX_EQ_SHIFT)
+#define RX_SMASK (RX_MASK << RX_SHIFT)
+
+#define TX_PRECUR_SHIFT 0
+#define TX_ATTN_SHIFT 4
+#define QSFP_TX_CDR_APPLY_SHIFT 9
+#define QSFP_TX_EQ_APPLY_SHIFT 10
+#define QSFP_TX_CDR_SHIFT 11
+#define QSFP_TX_EQ_SHIFT 12
+#define TX_POSTCUR_SHIFT 16
+
+#define TX_PRECUR_MASK 0xFUL
+#define TX_ATTN_MASK 0x1FUL
+#define QSFP_TX_CDR_APPLY_MASK 0x1UL
+#define QSFP_TX_EQ_APPLY_MASK 0x1UL
+#define QSFP_TX_CDR_MASK 0x1UL
+#define QSFP_TX_EQ_MASK 0xFUL
+#define TX_POSTCUR_MASK 0x1FUL
+
+#define TX_PRECUR_SMASK (TX_PRECUR_MASK << TX_PRECUR_SHIFT)
+#define TX_ATTN_SMASK (TX_ATTN_MASK << TX_ATTN_SHIFT)
+#define QSFP_TX_CDR_APPLY_SMASK (QSFP_TX_CDR_APPLY_MASK << \
+ QSFP_TX_CDR_APPLY_SHIFT)
+#define QSFP_TX_EQ_APPLY_SMASK (QSFP_TX_EQ_APPLY_MASK << \
+ QSFP_TX_EQ_APPLY_SHIFT)
+#define QSFP_TX_CDR_SMASK (QSFP_TX_CDR_MASK << QSFP_TX_CDR_SHIFT)
+#define QSFP_TX_EQ_SMASK (QSFP_TX_EQ_MASK << QSFP_TX_EQ_SHIFT)
+#define TX_POSTCUR_SMASK (TX_POSTCUR_MASK << TX_POSTCUR_SHIFT)
+
+#define QSFP_RX_CDR_APPLY_SHIFT 0
+#define QSFP_RX_EMP_APPLY_SHIFT 1
+#define QSFP_RX_AMP_APPLY_SHIFT 2
+#define QSFP_RX_CDR_SHIFT 3
+#define QSFP_RX_EMP_SHIFT 4
+#define QSFP_RX_AMP_SHIFT 8
+
+#define QSFP_RX_CDR_APPLY_MASK 0x1UL
+#define QSFP_RX_EMP_APPLY_MASK 0x1UL
+#define QSFP_RX_AMP_APPLY_MASK 0x1UL
+#define QSFP_RX_CDR_MASK 0x1UL
+#define QSFP_RX_EMP_MASK 0xFUL
+#define QSFP_RX_AMP_MASK 0x3UL
+
+#define QSFP_RX_CDR_APPLY_SMASK (QSFP_RX_CDR_APPLY_MASK << \
+ QSFP_RX_CDR_APPLY_SHIFT)
+#define QSFP_RX_EMP_APPLY_SMASK (QSFP_RX_EMP_APPLY_MASK << \
+ QSFP_RX_EMP_APPLY_SHIFT)
+#define QSFP_RX_AMP_APPLY_SMASK (QSFP_RX_AMP_APPLY_MASK << \
+ QSFP_RX_AMP_APPLY_SHIFT)
+#define QSFP_RX_CDR_SMASK (QSFP_RX_CDR_MASK << QSFP_RX_CDR_SHIFT)
+#define QSFP_RX_EMP_SMASK (QSFP_RX_EMP_MASK << QSFP_RX_EMP_SHIFT)
+#define QSFP_RX_AMP_SMASK (QSFP_RX_AMP_MASK << QSFP_RX_AMP_SHIFT)
+
+#define BITMAP_VERSION 1
+#define BITMAP_VERSION_SHIFT 44
+#define BITMAP_VERSION_MASK 0xFUL
+#define BITMAP_VERSION_SMASK (BITMAP_VERSION_MASK << \
+ BITMAP_VERSION_SHIFT)
+#define CHECKSUM_SHIFT 48
+#define CHECKSUM_MASK 0xFFFFUL
+#define CHECKSUM_SMASK (CHECKSUM_MASK << CHECKSUM_SHIFT)
+
/* platform.c */
void get_platform_config(struct hfi1_devdata *dd);
void free_platform_config(struct hfi1_devdata *dd);
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
index 9fc75e7e8781..d752d6768a49 100644
--- a/drivers/infiniband/hw/hfi1/qp.c
+++ b/drivers/infiniband/hw/hfi1/qp.c
@@ -196,15 +196,18 @@ static void flush_tx_list(struct rvt_qp *qp)
static void flush_iowait(struct rvt_qp *qp)
{
struct hfi1_qp_priv *priv = qp->priv;
- struct hfi1_ibdev *dev = to_idev(qp->ibqp.device);
unsigned long flags;
+ seqlock_t *lock = priv->s_iowait.lock;
- write_seqlock_irqsave(&dev->iowait_lock, flags);
+ if (!lock)
+ return;
+ write_seqlock_irqsave(lock, flags);
if (!list_empty(&priv->s_iowait.list)) {
list_del_init(&priv->s_iowait.list);
+ priv->s_iowait.lock = NULL;
rvt_put_qp(qp);
}
- write_sequnlock_irqrestore(&dev->iowait_lock, flags);
+ write_sequnlock_irqrestore(lock, flags);
}
static inline int opa_mtu_enum_to_int(int mtu)
@@ -543,6 +546,7 @@ static int iowait_sleep(
ibp->rvp.n_dmawait++;
qp->s_flags |= RVT_S_WAIT_DMA_DESC;
list_add_tail(&priv->s_iowait.list, &sde->dmawait);
+ priv->s_iowait.lock = &dev->iowait_lock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_DMA_DESC);
rvt_get_qp(qp);
}
@@ -964,6 +968,7 @@ void notify_error_qp(struct rvt_qp *qp)
if (!list_empty(&priv->s_iowait.list) && !(qp->s_flags & RVT_S_BUSY)) {
qp->s_flags &= ~RVT_S_ANY_WAIT_IO;
list_del_init(&priv->s_iowait.list);
+ priv->s_iowait.lock = NULL;
rvt_put_qp(qp);
}
write_sequnlock(&dev->iowait_lock);
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
index 83198a8a8797..809b26eb6d3c 100644
--- a/drivers/infiniband/hw/hfi1/rc.c
+++ b/drivers/infiniband/hw/hfi1/rc.c
@@ -276,7 +276,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
rvt_get_mr(ps->s_txreq->mr);
qp->s_ack_rdma_sge.sge = e->rdma_sge;
qp->s_ack_rdma_sge.num_sge = 1;
- qp->s_cur_sge = &qp->s_ack_rdma_sge;
+ ps->s_txreq->ss = &qp->s_ack_rdma_sge;
if (len > pmtu) {
len = pmtu;
qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST);
@@ -290,7 +290,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
bth2 = mask_psn(qp->s_ack_rdma_psn++);
} else {
/* COMPARE_SWAP or FETCH_ADD */
- qp->s_cur_sge = NULL;
+ ps->s_txreq->ss = NULL;
len = 0;
qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE);
ohdr->u.at.aeth = hfi1_compute_aeth(qp);
@@ -306,7 +306,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
qp->s_ack_state = OP(RDMA_READ_RESPONSE_MIDDLE);
/* FALLTHROUGH */
case OP(RDMA_READ_RESPONSE_MIDDLE):
- qp->s_cur_sge = &qp->s_ack_rdma_sge;
+ ps->s_txreq->ss = &qp->s_ack_rdma_sge;
ps->s_txreq->mr = qp->s_ack_rdma_sge.sge.mr;
if (ps->s_txreq->mr)
rvt_get_mr(ps->s_txreq->mr);
@@ -335,7 +335,7 @@ normal:
*/
qp->s_ack_state = OP(SEND_ONLY);
qp->s_flags &= ~RVT_S_ACK_PENDING;
- qp->s_cur_sge = NULL;
+ ps->s_txreq->ss = NULL;
if (qp->s_nak_state)
ohdr->u.aeth =
cpu_to_be32((qp->r_msn & HFI1_MSN_MASK) |
@@ -351,7 +351,7 @@ normal:
qp->s_rdma_ack_cnt++;
qp->s_hdrwords = hwords;
ps->s_txreq->sde = priv->s_sde;
- qp->s_cur_size = len;
+ ps->s_txreq->s_cur_size = len;
hfi1_make_ruc_header(qp, ohdr, bth0, bth2, middle, ps);
/* pbc */
ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
@@ -801,8 +801,8 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
qp->s_len -= len;
qp->s_hdrwords = hwords;
ps->s_txreq->sde = priv->s_sde;
- qp->s_cur_sge = ss;
- qp->s_cur_size = len;
+ ps->s_txreq->ss = ss;
+ ps->s_txreq->s_cur_size = len;
hfi1_make_ruc_header(
qp,
ohdr,
@@ -1146,8 +1146,6 @@ void hfi1_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
{
struct ib_other_headers *ohdr;
struct rvt_swqe *wqe;
- struct ib_wc wc;
- unsigned i;
u32 opcode;
u32 psn;
@@ -1195,22 +1193,8 @@ void hfi1_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
qp->s_last = s_last;
/* see post_send() */
barrier();
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
-
- rvt_put_mr(sge->mr);
- }
- /* Post a send completion queue entry if requested. */
- if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
- (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
- memset(&wc, 0, sizeof(wc));
- wc.wr_id = wqe->wr.wr_id;
- wc.status = IB_WC_SUCCESS;
- wc.opcode = ib_hfi1_wc_opcode[wqe->wr.opcode];
- wc.byte_len = wqe->length;
- wc.qp = &qp->ibqp;
- rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
- }
+ rvt_put_swqe(wqe);
+ rvt_qp_swqe_complete(qp, wqe, IB_WC_SUCCESS);
}
/*
* If we were waiting for sends to complete before re-sending,
@@ -1240,9 +1224,6 @@ static struct rvt_swqe *do_rc_completion(struct rvt_qp *qp,
struct rvt_swqe *wqe,
struct hfi1_ibport *ibp)
{
- struct ib_wc wc;
- unsigned i;
-
lockdep_assert_held(&qp->s_lock);
/*
* Don't decrement refcount and don't generate a
@@ -1253,28 +1234,14 @@ static struct rvt_swqe *do_rc_completion(struct rvt_qp *qp,
cmp_psn(qp->s_sending_psn, qp->s_sending_hpsn) > 0) {
u32 s_last;
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
-
- rvt_put_mr(sge->mr);
- }
+ rvt_put_swqe(wqe);
s_last = qp->s_last;
if (++s_last >= qp->s_size)
s_last = 0;
qp->s_last = s_last;
/* see post_send() */
barrier();
- /* Post a send completion queue entry if requested. */
- if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
- (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
- memset(&wc, 0, sizeof(wc));
- wc.wr_id = wqe->wr.wr_id;
- wc.status = IB_WC_SUCCESS;
- wc.opcode = ib_hfi1_wc_opcode[wqe->wr.opcode];
- wc.byte_len = wqe->length;
- wc.qp = &qp->ibqp;
- rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
- }
+ rvt_qp_swqe_complete(qp, wqe, IB_WC_SUCCESS);
} else {
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
@@ -2295,7 +2262,7 @@ send_last:
hfi1_copy_sge(&qp->r_sge, data, tlen, 1, copy_last);
rvt_put_ss(&qp->r_sge);
qp->r_msn++;
- if (!test_and_clear_bit(RVT_R_WRID_VALID, &qp->r_aflags))
+ if (!__test_and_clear_bit(RVT_R_WRID_VALID, &qp->r_aflags))
break;
wc.wr_id = qp->r_wr_id;
wc.status = IB_WC_SUCCESS;
@@ -2410,8 +2377,7 @@ send_last:
* Update the next expected PSN. We add 1 later
* below, so only add the remainder here.
*/
- if (len > pmtu)
- qp->r_psn += (len - 1) / pmtu;
+ qp->r_psn += rvt_div_mtu(qp, len - 1);
} else {
e->rdma_sge.mr = NULL;
e->rdma_sge.vaddr = NULL;
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c
index a1576aea4756..717ed4b159d3 100644
--- a/drivers/infiniband/hw/hfi1/ruc.c
+++ b/drivers/infiniband/hw/hfi1/ruc.c
@@ -239,16 +239,6 @@ bail:
return ret;
}
-static __be64 get_sguid(struct hfi1_ibport *ibp, unsigned index)
-{
- if (!index) {
- struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
-
- return cpu_to_be64(ppd->guid);
- }
- return ibp->guids[index - 1];
-}
-
static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id)
{
return (gid->global.interface_id == id &&
@@ -699,9 +689,9 @@ u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr,
/* The SGID is 32-bit aligned. */
hdr->sgid.global.subnet_prefix = ibp->rvp.gid_prefix;
hdr->sgid.global.interface_id =
- grh->sgid_index && grh->sgid_index < ARRAY_SIZE(ibp->guids) ?
- ibp->guids[grh->sgid_index - 1] :
- cpu_to_be64(ppd_from_ibp(ibp)->guid);
+ grh->sgid_index < HFI1_GUIDS_PER_PORT ?
+ get_sguid(ibp, grh->sgid_index) :
+ get_sguid(ibp, HFI1_PORT_GUID_INDEX);
hdr->dgid = grh->dgid;
/* GRH header size in 32-bit words. */
@@ -777,8 +767,8 @@ void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr,
u32 bth1;
/* Construct the header. */
- extra_bytes = -qp->s_cur_size & 3;
- nwords = (qp->s_cur_size + extra_bytes) >> 2;
+ extra_bytes = -ps->s_txreq->s_cur_size & 3;
+ nwords = (ps->s_txreq->s_cur_size + extra_bytes) >> 2;
lrh0 = HFI1_LRH_BTH;
if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) {
qp->s_hdrwords += hfi1_make_grh(ibp,
@@ -952,7 +942,6 @@ void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
enum ib_wc_status status)
{
u32 old_last, last;
- unsigned i;
if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_OR_FLUSH_SEND))
return;
@@ -964,32 +953,13 @@ void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
qp->s_last = last;
/* See post_send() */
barrier();
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
-
- rvt_put_mr(sge->mr);
- }
+ rvt_put_swqe(wqe);
if (qp->ibqp.qp_type == IB_QPT_UD ||
qp->ibqp.qp_type == IB_QPT_SMI ||
qp->ibqp.qp_type == IB_QPT_GSI)
atomic_dec(&ibah_to_rvtah(wqe->ud_wr.ah)->refcount);
- /* See ch. 11.2.4.1 and 10.7.3.1 */
- if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
- (wqe->wr.send_flags & IB_SEND_SIGNALED) ||
- status != IB_WC_SUCCESS) {
- struct ib_wc wc;
-
- memset(&wc, 0, sizeof(wc));
- wc.wr_id = wqe->wr.wr_id;
- wc.status = status;
- wc.opcode = ib_hfi1_wc_opcode[wqe->wr.opcode];
- wc.qp = &qp->ibqp;
- if (status == IB_WC_SUCCESS)
- wc.byte_len = wqe->length;
- rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc,
- status != IB_WC_SUCCESS);
- }
+ rvt_qp_swqe_complete(qp, wqe, status);
if (qp->s_acked == old_last)
qp->s_acked = last;
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
index 9cbe52d21077..1d81cac1fa6c 100644
--- a/drivers/infiniband/hw/hfi1/sdma.c
+++ b/drivers/infiniband/hw/hfi1/sdma.c
@@ -375,7 +375,7 @@ static inline void complete_tx(struct sdma_engine *sde,
sde->head_sn, tx->sn);
sde->head_sn++;
#endif
- sdma_txclean(sde->dd, tx);
+ __sdma_txclean(sde->dd, tx);
if (complete)
(*complete)(tx, res);
if (wait && iowait_sdma_dec(wait))
@@ -1643,7 +1643,7 @@ static inline u8 ahg_mode(struct sdma_txreq *tx)
}
/**
- * sdma_txclean() - clean tx of mappings, descp *kmalloc's
+ * __sdma_txclean() - clean tx of mappings, descp *kmalloc's
* @dd: hfi1_devdata for unmapping
* @tx: tx request to clean
*
@@ -1653,7 +1653,7 @@ static inline u8 ahg_mode(struct sdma_txreq *tx)
* The code can be called multiple times without issue.
*
*/
-void sdma_txclean(
+void __sdma_txclean(
struct hfi1_devdata *dd,
struct sdma_txreq *tx)
{
@@ -3065,7 +3065,7 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
tx->descp[i] = tx->descs[i];
return 0;
enomem:
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return -ENOMEM;
}
@@ -3094,14 +3094,14 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
rval = _extend_sdma_tx_descs(dd, tx);
if (rval) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return rval;
}
/* If coalesce buffer is allocated, copy data into it */
if (tx->coalesce_buf) {
if (type == SDMA_MAP_NONE) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return -EINVAL;
}
@@ -3109,7 +3109,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
kvaddr = kmap(page);
kvaddr += offset;
} else if (WARN_ON(!kvaddr)) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return -EINVAL;
}
@@ -3139,7 +3139,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&dd->pcidev->dev, addr))) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return -ENOSPC;
}
@@ -3181,7 +3181,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
if ((unlikely(tx->num_desc == tx->desc_limit))) {
rval = _extend_sdma_tx_descs(dd, tx);
if (rval) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return rval;
}
}
diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h
index 56257ea3598f..21f1e2834f37 100644
--- a/drivers/infiniband/hw/hfi1/sdma.h
+++ b/drivers/infiniband/hw/hfi1/sdma.h
@@ -667,7 +667,13 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
int type, void *kvaddr, struct page *page,
unsigned long offset, u16 len);
int _pad_sdma_tx_descs(struct hfi1_devdata *, struct sdma_txreq *);
-void sdma_txclean(struct hfi1_devdata *, struct sdma_txreq *);
+void __sdma_txclean(struct hfi1_devdata *, struct sdma_txreq *);
+
+static inline void sdma_txclean(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+{
+ if (tx->num_desc)
+ __sdma_txclean(dd, tx);
+}
/* helpers used by public routines */
static inline void _sdma_close_tx(struct hfi1_devdata *dd,
@@ -753,7 +759,7 @@ static inline int sdma_txadd_page(
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&dd->pcidev->dev, addr))) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return -ENOSPC;
}
@@ -834,7 +840,7 @@ static inline int sdma_txadd_kvaddr(
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&dd->pcidev->dev, addr))) {
- sdma_txclean(dd, tx);
+ __sdma_txclean(dd, tx);
return -ENOSPC;
}
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c
index 5e6d1bac4914..b141a78ae38b 100644
--- a/drivers/infiniband/hw/hfi1/uc.c
+++ b/drivers/infiniband/hw/hfi1/uc.c
@@ -258,8 +258,8 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
qp->s_len -= len;
qp->s_hdrwords = hwords;
ps->s_txreq->sde = priv->s_sde;
- qp->s_cur_sge = &qp->s_sge;
- qp->s_cur_size = len;
+ ps->s_txreq->ss = &qp->s_sge;
+ ps->s_txreq->s_cur_size = len;
hfi1_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24),
mask_psn(qp->s_psn++), middle, ps);
/* pbc */
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c
index 97ae24b6314c..c071955c0272 100644
--- a/drivers/infiniband/hw/hfi1/ud.c
+++ b/drivers/infiniband/hw/hfi1/ud.c
@@ -354,8 +354,8 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
/* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */
qp->s_hdrwords = 7;
- qp->s_cur_size = wqe->length;
- qp->s_cur_sge = &qp->s_sge;
+ ps->s_txreq->s_cur_size = wqe->length;
+ ps->s_txreq->ss = &qp->s_sge;
qp->s_srate = ah_attr->static_rate;
qp->srate_mbps = ib_rate_to_mbps(qp->s_srate);
qp->s_wqe = wqe;
diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c
index 77697d690f3e..7d22f8ee98ef 100644
--- a/drivers/infiniband/hw/hfi1/user_sdma.c
+++ b/drivers/infiniband/hw/hfi1/user_sdma.c
@@ -115,6 +115,7 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12
#define KDETH_HCRC_LOWER_MASK 0xff
#define AHG_KDETH_INTR_SHIFT 12
+#define AHG_KDETH_SH_SHIFT 13
#define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4)
#define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff)
@@ -144,8 +145,9 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12
#define KDETH_OM_LARGE 64
#define KDETH_OM_MAX_SIZE (1 << ((KDETH_OM_LARGE / KDETH_OM_SMALL) + 1))
-/* Last packet in the request */
-#define TXREQ_FLAGS_REQ_LAST_PKT BIT(0)
+/* Tx request flag bits */
+#define TXREQ_FLAGS_REQ_ACK BIT(0) /* Set the ACK bit in the header */
+#define TXREQ_FLAGS_REQ_DISABLE_SH BIT(1) /* Disable header suppression */
/* SDMA request flag bits */
#define SDMA_REQ_FOR_THREAD 1
@@ -943,8 +945,13 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
tx->busycount = 0;
INIT_LIST_HEAD(&tx->list);
+ /*
+ * For the last packet set the ACK request
+ * and disable header suppression.
+ */
if (req->seqnum == req->info.npkts - 1)
- tx->flags |= TXREQ_FLAGS_REQ_LAST_PKT;
+ tx->flags |= (TXREQ_FLAGS_REQ_ACK |
+ TXREQ_FLAGS_REQ_DISABLE_SH);
/*
* Calculate the payload size - this is min of the fragment
@@ -963,11 +970,22 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
}
datalen = compute_data_length(req, tx);
+
+ /*
+ * Disable header suppression for the payload <= 8DWS.
+ * If there is an uncorrectable error in the receive
+ * data FIFO when the received payload size is less than
+ * or equal to 8DWS then the RxDmaDataFifoRdUncErr is
+ * not reported.There is set RHF.EccErr if the header
+ * is not suppressed.
+ */
if (!datalen) {
SDMA_DBG(req,
"Request has data but pkt len is 0");
ret = -EFAULT;
goto free_tx;
+ } else if (datalen <= 32) {
+ tx->flags |= TXREQ_FLAGS_REQ_DISABLE_SH;
}
}
@@ -990,6 +1008,10 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
LRH2PBC(lrhlen);
tx->hdr.pbc[0] = cpu_to_le16(pbclen);
}
+ ret = check_header_template(req, &tx->hdr,
+ lrhlen, datalen);
+ if (ret)
+ goto free_tx;
ret = sdma_txinit_ahg(&tx->txreq,
SDMA_TXREQ_F_AHG_COPY,
sizeof(tx->hdr) + datalen,
@@ -1351,7 +1373,7 @@ static int set_txreq_header(struct user_sdma_request *req,
req->seqnum));
/* Set ACK request on last packet */
- if (unlikely(tx->flags & TXREQ_FLAGS_REQ_LAST_PKT))
+ if (unlikely(tx->flags & TXREQ_FLAGS_REQ_ACK))
hdr->bth[2] |= cpu_to_be32(1UL << 31);
/* Set the new offset */
@@ -1384,8 +1406,8 @@ static int set_txreq_header(struct user_sdma_request *req,
/* Set KDETH.TID based on value for this TID */
KDETH_SET(hdr->kdeth.ver_tid_offset, TID,
EXP_TID_GET(tidval, IDX));
- /* Clear KDETH.SH only on the last packet */
- if (unlikely(tx->flags & TXREQ_FLAGS_REQ_LAST_PKT))
+ /* Clear KDETH.SH when DISABLE_SH flag is set */
+ if (unlikely(tx->flags & TXREQ_FLAGS_REQ_DISABLE_SH))
KDETH_SET(hdr->kdeth.ver_tid_offset, SH, 0);
/*
* Set the KDETH.OFFSET and KDETH.OM based on size of
@@ -1429,7 +1451,7 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
/* BTH.PSN and BTH.A */
val32 = (be32_to_cpu(hdr->bth[2]) + req->seqnum) &
(HFI1_CAP_IS_KSET(EXTENDED_PSN) ? 0x7fffffff : 0xffffff);
- if (unlikely(tx->flags & TXREQ_FLAGS_REQ_LAST_PKT))
+ if (unlikely(tx->flags & TXREQ_FLAGS_REQ_ACK))
val32 |= 1UL << 31;
AHG_HEADER_SET(req->ahg, diff, 6, 0, 16, cpu_to_be16(val32 >> 16));
AHG_HEADER_SET(req->ahg, diff, 6, 16, 16, cpu_to_be16(val32 & 0xffff));
@@ -1468,19 +1490,23 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
AHG_HEADER_SET(req->ahg, diff, 7, 0, 16,
((!!(req->omfactor - KDETH_OM_SMALL)) << 15 |
((req->tidoffset / req->omfactor) & 0x7fff)));
- /* KDETH.TIDCtrl, KDETH.TID */
+ /* KDETH.TIDCtrl, KDETH.TID, KDETH.Intr, KDETH.SH */
val = cpu_to_le16(((EXP_TID_GET(tidval, CTRL) & 0x3) << 10) |
- (EXP_TID_GET(tidval, IDX) & 0x3ff));
- /* Clear KDETH.SH on last packet */
- if (unlikely(tx->flags & TXREQ_FLAGS_REQ_LAST_PKT)) {
- val |= cpu_to_le16(KDETH_GET(hdr->kdeth.ver_tid_offset,
- INTR) <<
- AHG_KDETH_INTR_SHIFT);
- val &= cpu_to_le16(~(1U << 13));
- AHG_HEADER_SET(req->ahg, diff, 7, 16, 14, val);
+ (EXP_TID_GET(tidval, IDX) & 0x3ff));
+
+ if (unlikely(tx->flags & TXREQ_FLAGS_REQ_DISABLE_SH)) {
+ val |= cpu_to_le16((KDETH_GET(hdr->kdeth.ver_tid_offset,
+ INTR) <<
+ AHG_KDETH_INTR_SHIFT));
} else {
- AHG_HEADER_SET(req->ahg, diff, 7, 16, 12, val);
+ val |= KDETH_GET(hdr->kdeth.ver_tid_offset, SH) ?
+ cpu_to_le16(0x1 << AHG_KDETH_SH_SHIFT) :
+ cpu_to_le16((KDETH_GET(hdr->kdeth.ver_tid_offset,
+ INTR) <<
+ AHG_KDETH_INTR_SHIFT));
}
+
+ AHG_HEADER_SET(req->ahg, diff, 7, 16, 14, val);
}
trace_hfi1_sdma_user_header_ahg(pq->dd, pq->ctxt, pq->subctxt,
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
index 4b7a16ceb362..95ed4d6da510 100644
--- a/drivers/infiniband/hw/hfi1/verbs.c
+++ b/drivers/infiniband/hw/hfi1/verbs.c
@@ -297,22 +297,6 @@ static inline int wss_exceeds_threshold(void)
}
/*
- * Translate ib_wr_opcode into ib_wc_opcode.
- */
-const enum ib_wc_opcode ib_hfi1_wc_opcode[] = {
- [IB_WR_RDMA_WRITE] = IB_WC_RDMA_WRITE,
- [IB_WR_RDMA_WRITE_WITH_IMM] = IB_WC_RDMA_WRITE,
- [IB_WR_SEND] = IB_WC_SEND,
- [IB_WR_SEND_WITH_IMM] = IB_WC_SEND,
- [IB_WR_RDMA_READ] = IB_WC_RDMA_READ,
- [IB_WR_ATOMIC_CMP_AND_SWP] = IB_WC_COMP_SWAP,
- [IB_WR_ATOMIC_FETCH_AND_ADD] = IB_WC_FETCH_ADD,
- [IB_WR_SEND_WITH_INV] = IB_WC_SEND,
- [IB_WR_LOCAL_INV] = IB_WC_LOCAL_INV,
- [IB_WR_REG_MR] = IB_WC_REG_MR
-};
-
-/*
* Length of header by opcode, 0 --> not supported
*/
const u8 hdr_len_by_opcode[256] = {
@@ -694,6 +678,7 @@ static void mem_timer(unsigned long data)
qp = iowait_to_qp(wait);
priv = qp->priv;
list_del_init(&priv->s_iowait.list);
+ priv->s_iowait.lock = NULL;
/* refcount held until actual wake up */
if (!list_empty(list))
mod_timer(&dev->mem_timer, jiffies + 1);
@@ -769,6 +754,7 @@ static int wait_kmem(struct hfi1_ibdev *dev,
mod_timer(&dev->mem_timer, jiffies + 1);
qp->s_flags |= RVT_S_WAIT_KMEM;
list_add_tail(&priv->s_iowait.list, &dev->memwait);
+ priv->s_iowait.lock = &dev->iowait_lock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_KMEM);
rvt_get_qp(qp);
}
@@ -788,10 +774,10 @@ static int wait_kmem(struct hfi1_ibdev *dev,
*/
static noinline int build_verbs_ulp_payload(
struct sdma_engine *sde,
- struct rvt_sge_state *ss,
u32 length,
struct verbs_txreq *tx)
{
+ struct rvt_sge_state *ss = tx->ss;
struct rvt_sge *sg_list = ss->sg_list;
struct rvt_sge sge = ss->sge;
u8 num_sge = ss->num_sge;
@@ -835,7 +821,6 @@ bail_txadd:
/* New API */
static int build_verbs_tx_desc(
struct sdma_engine *sde,
- struct rvt_sge_state *ss,
u32 length,
struct verbs_txreq *tx,
struct hfi1_ahg_info *ahg_info,
@@ -879,9 +864,9 @@ static int build_verbs_tx_desc(
goto bail_txadd;
}
- /* add the ulp payload - if any. ss can be NULL for acks */
- if (ss)
- ret = build_verbs_ulp_payload(sde, ss, length, tx);
+ /* add the ulp payload - if any. tx->ss can be NULL for acks */
+ if (tx->ss)
+ ret = build_verbs_ulp_payload(sde, length, tx);
bail_txadd:
return ret;
}
@@ -892,8 +877,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
struct hfi1_qp_priv *priv = qp->priv;
struct hfi1_ahg_info *ahg_info = priv->s_ahg;
u32 hdrwords = qp->s_hdrwords;
- struct rvt_sge_state *ss = qp->s_cur_sge;
- u32 len = qp->s_cur_size;
+ u32 len = ps->s_txreq->s_cur_size;
u32 plen = hdrwords + ((len + 3) >> 2) + 2; /* includes pbc */
struct hfi1_ibdev *dev = ps->dev;
struct hfi1_pportdata *ppd = ps->ppd;
@@ -918,7 +902,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
plen);
}
tx->wqe = qp->s_wqe;
- ret = build_verbs_tx_desc(tx->sde, ss, len, tx, ahg_info, pbc);
+ ret = build_verbs_tx_desc(tx->sde, len, tx, ahg_info, pbc);
if (unlikely(ret))
goto bail_build;
}
@@ -980,6 +964,7 @@ static int pio_wait(struct rvt_qp *qp,
qp->s_flags |= flag;
was_empty = list_empty(&sc->piowait);
list_add_tail(&priv->s_iowait.list, &sc->piowait);
+ priv->s_iowait.lock = &dev->iowait_lock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_PIO);
rvt_get_qp(qp);
/* counting: only call wantpiobuf_intr if first user */
@@ -1008,8 +993,8 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
{
struct hfi1_qp_priv *priv = qp->priv;
u32 hdrwords = qp->s_hdrwords;
- struct rvt_sge_state *ss = qp->s_cur_sge;
- u32 len = qp->s_cur_size;
+ struct rvt_sge_state *ss = ps->s_txreq->ss;
+ u32 len = ps->s_txreq->s_cur_size;
u32 dwords = (len + 3) >> 2;
u32 plen = hdrwords + dwords + 2; /* includes pbc */
struct hfi1_pportdata *ppd = ps->ppd;
@@ -1237,7 +1222,7 @@ static inline send_routine get_send_routine(struct rvt_qp *qp,
u8 op = get_opcode(h);
if (piothreshold &&
- qp->s_cur_size <= min(piothreshold, qp->pmtu) &&
+ tx->s_cur_size <= min(piothreshold, qp->pmtu) &&
(BIT(op & OPMASK) & pio_opmask[op >> 5]) &&
iowait_sdma_pending(&priv->s_iowait) == 0 &&
!sdma_txreq_built(&tx->txreq))
@@ -1483,15 +1468,11 @@ static int hfi1_get_guid_be(struct rvt_dev_info *rdi, struct rvt_ibport *rvp,
int guid_index, __be64 *guid)
{
struct hfi1_ibport *ibp = container_of(rvp, struct hfi1_ibport, rvp);
- struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
- if (guid_index == 0)
- *guid = cpu_to_be64(ppd->guid);
- else if (guid_index < HFI1_GUIDS_PER_PORT)
- *guid = ibp->guids[guid_index - 1];
- else
+ if (guid_index >= HFI1_GUIDS_PER_PORT)
return -EINVAL;
+ *guid = get_sguid(ibp, guid_index);
return 0;
}
@@ -1610,6 +1591,154 @@ static void hfi1_get_dev_fw_str(struct ib_device *ibdev, char *str,
dc8051_ver_min(ver));
}
+static const char * const driver_cntr_names[] = {
+ /* must be element 0*/
+ "DRIVER_KernIntr",
+ "DRIVER_ErrorIntr",
+ "DRIVER_Tx_Errs",
+ "DRIVER_Rcv_Errs",
+ "DRIVER_HW_Errs",
+ "DRIVER_NoPIOBufs",
+ "DRIVER_CtxtsOpen",
+ "DRIVER_RcvLen_Errs",
+ "DRIVER_EgrBufFull",
+ "DRIVER_EgrHdrFull"
+};
+
+static const char **dev_cntr_names;
+static const char **port_cntr_names;
+static int num_driver_cntrs = ARRAY_SIZE(driver_cntr_names);
+static int num_dev_cntrs;
+static int num_port_cntrs;
+static int cntr_names_initialized;
+
+/*
+ * Convert a list of names separated by '\n' into an array of NULL terminated
+ * strings. Optionally some entries can be reserved in the array to hold extra
+ * external strings.
+ */
+static int init_cntr_names(const char *names_in,
+ const int names_len,
+ int num_extra_names,
+ int *num_cntrs,
+ const char ***cntr_names)
+{
+ char *names_out, *p, **q;
+ int i, n;
+
+ n = 0;
+ for (i = 0; i < names_len; i++)
+ if (names_in[i] == '\n')
+ n++;
+
+ names_out = kmalloc((n + num_extra_names) * sizeof(char *) + names_len,
+ GFP_KERNEL);
+ if (!names_out) {
+ *num_cntrs = 0;
+ *cntr_names = NULL;
+ return -ENOMEM;
+ }
+
+ p = names_out + (n + num_extra_names) * sizeof(char *);
+ memcpy(p, names_in, names_len);
+
+ q = (char **)names_out;
+ for (i = 0; i < n; i++) {
+ q[i] = p;
+ p = strchr(p, '\n');
+ *p++ = '\0';
+ }
+
+ *num_cntrs = n;
+ *cntr_names = (const char **)names_out;
+ return 0;
+}
+
+static struct rdma_hw_stats *alloc_hw_stats(struct ib_device *ibdev,
+ u8 port_num)
+{
+ int i, err;
+
+ if (!cntr_names_initialized) {
+ struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
+
+ err = init_cntr_names(dd->cntrnames,
+ dd->cntrnameslen,
+ num_driver_cntrs,
+ &num_dev_cntrs,
+ &dev_cntr_names);
+ if (err)
+ return NULL;
+
+ for (i = 0; i < num_driver_cntrs; i++)
+ dev_cntr_names[num_dev_cntrs + i] =
+ driver_cntr_names[i];
+
+ err = init_cntr_names(dd->portcntrnames,
+ dd->portcntrnameslen,
+ 0,
+ &num_port_cntrs,
+ &port_cntr_names);
+ if (err) {
+ kfree(dev_cntr_names);
+ dev_cntr_names = NULL;
+ return NULL;
+ }
+ cntr_names_initialized = 1;
+ }
+
+ if (!port_num)
+ return rdma_alloc_hw_stats_struct(
+ dev_cntr_names,
+ num_dev_cntrs + num_driver_cntrs,
+ RDMA_HW_STATS_DEFAULT_LIFESPAN);
+ else
+ return rdma_alloc_hw_stats_struct(
+ port_cntr_names,
+ num_port_cntrs,
+ RDMA_HW_STATS_DEFAULT_LIFESPAN);
+}
+
+static u64 hfi1_sps_ints(void)
+{
+ unsigned long flags;
+ struct hfi1_devdata *dd;
+ u64 sps_ints = 0;
+
+ spin_lock_irqsave(&hfi1_devs_lock, flags);
+ list_for_each_entry(dd, &hfi1_dev_list, list) {
+ sps_ints += get_all_cpu_total(dd->int_counter);
+ }
+ spin_unlock_irqrestore(&hfi1_devs_lock, flags);
+ return sps_ints;
+}
+
+static int get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats,
+ u8 port, int index)
+{
+ u64 *values;
+ int count;
+
+ if (!port) {
+ u64 *stats = (u64 *)&hfi1_stats;
+ int i;
+
+ hfi1_read_cntrs(dd_from_ibdev(ibdev), NULL, &values);
+ values[num_dev_cntrs] = hfi1_sps_ints();
+ for (i = 1; i < num_driver_cntrs; i++)
+ values[num_dev_cntrs + i] = stats[i];
+ count = num_dev_cntrs + num_driver_cntrs;
+ } else {
+ struct hfi1_ibport *ibp = to_iport(ibdev, port);
+
+ hfi1_read_portcntrs(ppd_from_ibp(ibp), NULL, &values);
+ count = num_port_cntrs;
+ }
+
+ memcpy(stats->value, values, count * sizeof(u64));
+ return count;
+}
+
/**
* hfi1_register_ib_device - register our device with the infiniband core
* @dd: the device data structure
@@ -1620,6 +1749,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
struct hfi1_ibdev *dev = &dd->verbs_dev;
struct ib_device *ibdev = &dev->rdi.ibdev;
struct hfi1_pportdata *ppd = dd->pport;
+ struct hfi1_ibport *ibp = &ppd->ibport_data;
unsigned i;
int ret;
size_t lcpysz = IB_DEVICE_NAME_MAX;
@@ -1632,6 +1762,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
setup_timer(&dev->mem_timer, mem_timer, (unsigned long)dev);
seqlock_init(&dev->iowait_lock);
+ seqlock_init(&dev->txwait_lock);
INIT_LIST_HEAD(&dev->txwait);
INIT_LIST_HEAD(&dev->memwait);
@@ -1639,20 +1770,24 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
if (ret)
goto err_verbs_txreq;
+ /* Use first-port GUID as node guid */
+ ibdev->node_guid = get_sguid(ibp, HFI1_PORT_GUID_INDEX);
+
/*
* The system image GUID is supposed to be the same for all
* HFIs in a single system but since there can be other
* device types in the system, we can't be sure this is unique.
*/
if (!ib_hfi1_sys_image_guid)
- ib_hfi1_sys_image_guid = cpu_to_be64(ppd->guid);
+ ib_hfi1_sys_image_guid = ibdev->node_guid;
lcpysz = strlcpy(ibdev->name, class_name(), lcpysz);
strlcpy(ibdev->name + lcpysz, "_%d", IB_DEVICE_NAME_MAX - lcpysz);
ibdev->owner = THIS_MODULE;
- ibdev->node_guid = cpu_to_be64(ppd->guid);
ibdev->phys_port_cnt = dd->num_pports;
ibdev->dma_device = &dd->pcidev->dev;
ibdev->modify_device = modify_device;
+ ibdev->alloc_hw_stats = alloc_hw_stats;
+ ibdev->get_hw_stats = get_hw_stats;
/* keep process mad in the driver */
ibdev->process_mad = hfi1_process_mad;
@@ -1767,6 +1902,10 @@ void hfi1_unregister_ib_device(struct hfi1_devdata *dd)
del_timer_sync(&dev->mem_timer);
verbs_txreq_exit(dev);
+
+ kfree(dev_cntr_names);
+ kfree(port_cntr_names);
+ cntr_names_initialized = 0;
}
void hfi1_cnp_rcv(struct hfi1_packet *packet)
diff --git a/drivers/infiniband/hw/hfi1/verbs.h b/drivers/infiniband/hw/hfi1/verbs.h
index 1c3815d89eb7..e6b893010e6d 100644
--- a/drivers/infiniband/hw/hfi1/verbs.h
+++ b/drivers/infiniband/hw/hfi1/verbs.h
@@ -73,7 +73,6 @@ struct hfi1_packet;
#include "iowait.h"
#define HFI1_MAX_RDMA_ATOMIC 16
-#define HFI1_GUIDS_PER_PORT 5
/*
* Increment this value if any changes that break userspace ABI
@@ -169,8 +168,6 @@ struct hfi1_ibport {
struct rvt_qp __rcu *qp[2];
struct rvt_ibport rvp;
- __be64 guids[HFI1_GUIDS_PER_PORT - 1]; /* writable GUIDs */
-
/* the first 16 entries are sl_to_vl for !OPA */
u8 sl_to_sc[32];
u8 sc_to_sl[32];
@@ -180,18 +177,19 @@ struct hfi1_ibdev {
struct rvt_dev_info rdi; /* Must be first */
/* QP numbers are shared by all IB ports */
- /* protect wait lists */
- seqlock_t iowait_lock;
+ /* protect txwait list */
+ seqlock_t txwait_lock ____cacheline_aligned_in_smp;
struct list_head txwait; /* list for wait verbs_txreq */
struct list_head memwait; /* list for wait kernel memory */
- struct list_head txreq_free;
struct kmem_cache *verbs_txreq_cache;
- struct timer_list mem_timer;
+ u64 n_txwait;
+ u64 n_kmem_wait;
+ /* protect iowait lists */
+ seqlock_t iowait_lock ____cacheline_aligned_in_smp;
u64 n_piowait;
u64 n_piodrain;
- u64 n_txwait;
- u64 n_kmem_wait;
+ struct timer_list mem_timer;
#ifdef CONFIG_DEBUG_FS
/* per HFI debugfs */
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.c b/drivers/infiniband/hw/hfi1/verbs_txreq.c
index 094ab829ec42..5d23172c470f 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.c
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.c
@@ -72,22 +72,22 @@ void hfi1_put_txreq(struct verbs_txreq *tx)
kmem_cache_free(dev->verbs_txreq_cache, tx);
do {
- seq = read_seqbegin(&dev->iowait_lock);
+ seq = read_seqbegin(&dev->txwait_lock);
if (!list_empty(&dev->txwait)) {
struct iowait *wait;
- write_seqlock_irqsave(&dev->iowait_lock, flags);
+ write_seqlock_irqsave(&dev->txwait_lock, flags);
wait = list_first_entry(&dev->txwait, struct iowait,
list);
qp = iowait_to_qp(wait);
priv = qp->priv;
list_del_init(&priv->s_iowait.list);
/* refcount held until actual wake up */
- write_sequnlock_irqrestore(&dev->iowait_lock, flags);
+ write_sequnlock_irqrestore(&dev->txwait_lock, flags);
hfi1_qp_wakeup(qp, RVT_S_WAIT_TX);
break;
}
- } while (read_seqretry(&dev->iowait_lock, seq));
+ } while (read_seqretry(&dev->txwait_lock, seq));
}
struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
@@ -96,7 +96,7 @@ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
{
struct verbs_txreq *tx = ERR_PTR(-EBUSY);
- write_seqlock(&dev->iowait_lock);
+ write_seqlock(&dev->txwait_lock);
if (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) {
struct hfi1_qp_priv *priv;
@@ -108,13 +108,14 @@ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
dev->n_txwait++;
qp->s_flags |= RVT_S_WAIT_TX;
list_add_tail(&priv->s_iowait.list, &dev->txwait);
+ priv->s_iowait.lock = &dev->txwait_lock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_TX);
rvt_get_qp(qp);
}
qp->s_flags &= ~RVT_S_BUSY;
}
out:
- write_sequnlock(&dev->iowait_lock);
+ write_sequnlock(&dev->txwait_lock);
return tx;
}
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.h b/drivers/infiniband/hw/hfi1/verbs_txreq.h
index 5660897593ba..76216f2ef35a 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.h
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.h
@@ -65,6 +65,7 @@ struct verbs_txreq {
struct sdma_engine *sde;
struct send_context *psc;
u16 hdr_dwords;
+ u16 s_cur_size;
};
struct hfi1_ibdev;
diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c
index 24f79ee39fdf..0ac294db3b29 100644
--- a/drivers/infiniband/hw/hns/hns_roce_ah.c
+++ b/drivers/infiniband/hw/hns/hns_roce_ah.c
@@ -39,7 +39,8 @@
#define HNS_ROCE_VLAN_SL_BIT_MASK 7
#define HNS_ROCE_VLAN_SL_SHIFT 13
-struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr)
+struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
{
struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
struct device *dev = &hr_dev->pdev->dev;
diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c
index 863a17a2de40..605962f2828c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_alloc.c
+++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
@@ -61,9 +61,10 @@ int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj)
return ret;
}
-void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj)
+void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj,
+ int rr)
{
- hns_roce_bitmap_free_range(bitmap, obj, 1);
+ hns_roce_bitmap_free_range(bitmap, obj, 1, rr);
}
int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
@@ -106,7 +107,8 @@ int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
}
void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
- unsigned long obj, int cnt)
+ unsigned long obj, int cnt,
+ int rr)
{
int i;
@@ -116,7 +118,8 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
for (i = 0; i < cnt; i++)
clear_bit(obj + i, bitmap->table);
- bitmap->last = min(bitmap->last, obj);
+ if (!rr)
+ bitmap->last = min(bitmap->last, obj);
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
& bitmap->mask;
spin_unlock(&bitmap->lock);
diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c
index 2a0b6c05da5f..8c1f7a6f84d2 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cmd.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c
@@ -216,10 +216,10 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param,
goto out;
/*
- * It is timeout when wait_for_completion_timeout return 0
- * The return value is the time limit set in advance
- * how many seconds showing
- */
+ * It is timeout when wait_for_completion_timeout return 0
+ * The return value is the time limit set in advance
+ * how many seconds showing
+ */
if (!wait_for_completion_timeout(&context->done,
msecs_to_jiffies(timeout))) {
dev_err(dev, "[cmd]wait_for_completion_timeout timeout\n");
diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.h b/drivers/infiniband/hw/hns/hns_roce_cmd.h
index e3997d312c55..f5a9ee2fc53d 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cmd.h
+++ b/drivers/infiniband/hw/hns/hns_roce_cmd.h
@@ -34,6 +34,7 @@
#define _HNS_ROCE_CMD_H
#define HNS_ROCE_MAILBOX_SIZE 4096
+#define HNS_ROCE_CMD_TIMEOUT_MSECS 10000
enum {
/* TPT commands */
@@ -57,17 +58,6 @@ enum {
HNS_ROCE_CMD_QUERY_QP = 0x22,
};
-enum {
- HNS_ROCE_CMD_TIME_CLASS_A = 10000,
- HNS_ROCE_CMD_TIME_CLASS_B = 10000,
- HNS_ROCE_CMD_TIME_CLASS_C = 10000,
-};
-
-struct hns_roce_cmd_mailbox {
- void *buf;
- dma_addr_t dma;
-};
-
int hns_roce_cmd_mbox(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param,
unsigned long in_modifier, u8 op_modifier, u16 op,
unsigned long timeout);
diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h b/drivers/infiniband/hw/hns/hns_roce_common.h
index 297016103aa7..4af403e1348c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -57,6 +57,32 @@
#define roce_set_bit(origin, shift, val) \
roce_set_field((origin), (1ul << (shift)), (shift), (val))
+/*
+ * roce_hw_index_cmp_lt - Compare two hardware index values in hisilicon
+ * SOC, check if a is less than b.
+ * @a: hardware index value
+ * @b: hardware index value
+ * @bits: the number of bits of a and b, range: 0~31.
+ *
+ * Hardware index increases continuously till max value, and then restart
+ * from zero, again and again. Because the bits of reg field is often
+ * limited, the reg field can only hold the low bits of the hardware index
+ * in hisilicon SOC.
+ * In some scenes we need to compare two values(a,b) getted from two reg
+ * fields in this driver, for example:
+ * If a equals 0xfffe, b equals 0x1 and bits equals 16, we think b has
+ * incresed from 0xffff to 0x1 and a is less than b.
+ * If a equals 0xfffe, b equals 0x0xf001 and bits equals 16, we think a
+ * is bigger than b.
+ *
+ * Return true on a less than b, otherwise false.
+ */
+#define roce_hw_index_mask(bits) ((1ul << (bits)) - 1)
+#define roce_hw_index_shift(bits) (32 - (bits))
+#define roce_hw_index_cmp_lt(a, b, bits) \
+ ((int)((((a) - (b)) & roce_hw_index_mask(bits)) << \
+ roce_hw_index_shift(bits)) < 0)
+
#define ROCEE_GLB_CFG_ROCEE_DB_SQ_MODE_S 3
#define ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S 4
@@ -245,16 +271,26 @@
#define ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M \
(((1UL << 28) - 1) << ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S)
+#define ROCEE_SDB_PTR_CMP_BITS 28
+
#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_S 0
#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_M \
(((1UL << 16) - 1) << ROCEE_SDB_INV_CNT_SDB_INV_CNT_S)
+#define ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S 0
+#define ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M \
+ (((1UL << 16) - 1) << ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S)
+
+#define ROCEE_SDB_CNT_CMP_BITS 16
+
+#define ROCEE_TSP_BP_ST_QH_FIFO_ENTRY_S 20
+
+#define ROCEE_CNT_CLR_CE_CNT_CLR_CE_S 0
+
/*************ROCEE_REG DEFINITION****************/
#define ROCEE_VENDOR_ID_REG 0x0
#define ROCEE_VENDOR_PART_ID_REG 0x4
-#define ROCEE_HW_VERSION_REG 0x8
-
#define ROCEE_SYS_IMAGE_GUID_L_REG 0xC
#define ROCEE_SYS_IMAGE_GUID_H_REG 0x10
@@ -318,7 +354,11 @@
#define ROCEE_SDB_ISSUE_PTR_REG 0x758
#define ROCEE_SDB_SEND_PTR_REG 0x75C
+#define ROCEE_CAEP_CQE_WCMD_EMPTY 0x850
+#define ROCEE_SCAEP_WR_CQE_CNT 0x8D0
#define ROCEE_SDB_INV_CNT_REG 0x9A4
+#define ROCEE_SDB_RETRY_CNT_REG 0x9AC
+#define ROCEE_TSP_BP_ST_REG 0x9EC
#define ROCEE_ECC_UCERR_ALM0_REG 0xB34
#define ROCEE_ECC_CERR_ALM0_REG 0xB40
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c
index 097365932b09..589496c8fb9e 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -35,7 +35,7 @@
#include "hns_roce_device.h"
#include "hns_roce_cmd.h"
#include "hns_roce_hem.h"
-#include "hns_roce_user.h"
+#include <rdma/hns-abi.h>
#include "hns_roce_common.h"
static void hns_roce_ib_cq_comp(struct hns_roce_cq *hr_cq)
@@ -77,7 +77,7 @@ static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev,
unsigned long cq_num)
{
return hns_roce_cmd_mbox(dev, mailbox->dma, 0, cq_num, 0,
- HNS_ROCE_CMD_SW2HW_CQ, HNS_ROCE_CMD_TIME_CLASS_A);
+ HNS_ROCE_CMD_SW2HW_CQ, HNS_ROCE_CMD_TIMEOUT_MSECS);
}
static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
@@ -166,7 +166,7 @@ err_put:
hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
err_out:
- hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn);
+ hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn, BITMAP_NO_RR);
return ret;
}
@@ -176,11 +176,10 @@ static int hns_roce_hw2sw_cq(struct hns_roce_dev *dev,
{
return hns_roce_cmd_mbox(dev, 0, mailbox ? mailbox->dma : 0, cq_num,
mailbox ? 0 : 1, HNS_ROCE_CMD_HW2SW_CQ,
- HNS_ROCE_CMD_TIME_CLASS_A);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
}
-static void hns_roce_free_cq(struct hns_roce_dev *hr_dev,
- struct hns_roce_cq *hr_cq)
+void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
{
struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
struct device *dev = &hr_dev->pdev->dev;
@@ -204,7 +203,7 @@ static void hns_roce_free_cq(struct hns_roce_dev *hr_dev,
spin_unlock_irq(&cq_table->lock);
hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
- hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn);
+ hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn, BITMAP_NO_RR);
}
static int hns_roce_ib_get_cq_umem(struct hns_roce_dev *hr_dev,
@@ -349,6 +348,15 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
goto err_mtt;
}
+ /*
+ * For the QP created by kernel space, tptr value should be initialized
+ * to zero; For the QP created by user space, it will cause synchronous
+ * problems if tptr is set to zero here, so we initialze it in user
+ * space.
+ */
+ if (!context)
+ *hr_cq->tptr_addr = 0;
+
/* Get created cq handler and carry out event */
hr_cq->comp = hns_roce_ib_cq_comp;
hr_cq->event = hns_roce_ib_cq_event;
@@ -383,19 +391,25 @@ int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq)
{
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
+ int ret = 0;
- hns_roce_free_cq(hr_dev, hr_cq);
- hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
+ if (hr_dev->hw->destroy_cq) {
+ ret = hr_dev->hw->destroy_cq(ib_cq);
+ } else {
+ hns_roce_free_cq(hr_dev, hr_cq);
+ hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
- if (ib_cq->uobject)
- ib_umem_release(hr_cq->umem);
- else
- /* Free the buff of stored cq */
- hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, ib_cq->cqe);
+ if (ib_cq->uobject)
+ ib_umem_release(hr_cq->umem);
+ else
+ /* Free the buff of stored cq */
+ hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
+ ib_cq->cqe);
- kfree(hr_cq);
+ kfree(hr_cq);
+ }
- return 0;
+ return ret;
}
void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index 341731553a60..1a6cb5d7a0dd 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -37,6 +37,8 @@
#define DRV_NAME "hns_roce"
+#define HNS_ROCE_HW_VER1 ('h' << 24 | 'i' << 16 | '0' << 8 | '6')
+
#define MAC_ADDR_OCTET_NUM 6
#define HNS_ROCE_MAX_MSG_LEN 0x80000000
@@ -54,6 +56,12 @@
#define HNS_ROCE_MAX_INNER_MTPT_NUM 0x7
#define HNS_ROCE_MAX_MTPT_PBL_NUM 0x100000
+#define HNS_ROCE_EACH_FREE_CQ_WAIT_MSECS 20
+#define HNS_ROCE_MAX_FREE_CQ_WAIT_CNT \
+ (5000 / HNS_ROCE_EACH_FREE_CQ_WAIT_MSECS)
+#define HNS_ROCE_CQE_WCMD_EMPTY_BIT 0x2
+#define HNS_ROCE_MIN_CQE_CNT 16
+
#define HNS_ROCE_MAX_IRQ_NUM 34
#define HNS_ROCE_COMP_VEC_NUM 32
@@ -70,6 +78,9 @@
#define HNS_ROCE_MAX_GID_NUM 16
#define HNS_ROCE_GID_SIZE 16
+#define BITMAP_NO_RR 0
+#define BITMAP_RR 1
+
#define MR_TYPE_MR 0x00
#define MR_TYPE_DMA 0x03
@@ -196,9 +207,9 @@ struct hns_roce_bitmap {
/* Order = 0: bitmap is biggest, order = max bitmap is least (only a bit) */
/* Every bit repesent to a partner free/used status in bitmap */
/*
-* Initial, bits of other bitmap are all 0 except that a bit of max_order is 1
-* Bit = 1 represent to idle and available; bit = 0: not available
-*/
+ * Initial, bits of other bitmap are all 0 except that a bit of max_order is 1
+ * Bit = 1 represent to idle and available; bit = 0: not available
+ */
struct hns_roce_buddy {
/* Members point to every order level bitmap */
unsigned long **bits;
@@ -296,7 +307,7 @@ struct hns_roce_cq {
u32 cq_depth;
u32 cons_index;
void __iomem *cq_db_l;
- void __iomem *tptr_addr;
+ u16 *tptr_addr;
unsigned long cqn;
u32 vector;
atomic_t refcount;
@@ -360,29 +371,34 @@ struct hns_roce_cmdq {
struct mutex hcr_mutex;
struct semaphore poll_sem;
/*
- * Event mode: cmd register mutex protection,
- * ensure to not exceed max_cmds and user use limit region
- */
+ * Event mode: cmd register mutex protection,
+ * ensure to not exceed max_cmds and user use limit region
+ */
struct semaphore event_sem;
int max_cmds;
spinlock_t context_lock;
int free_head;
struct hns_roce_cmd_context *context;
/*
- * Result of get integer part
- * which max_comds compute according a power of 2
- */
+ * Result of get integer part
+ * which max_comds compute according a power of 2
+ */
u16 token_mask;
/*
- * Process whether use event mode, init default non-zero
- * After the event queue of cmd event ready,
- * can switch into event mode
- * close device, switch into poll mode(non event mode)
- */
+ * Process whether use event mode, init default non-zero
+ * After the event queue of cmd event ready,
+ * can switch into event mode
+ * close device, switch into poll mode(non event mode)
+ */
u8 use_events;
u8 toggle;
};
+struct hns_roce_cmd_mailbox {
+ void *buf;
+ dma_addr_t dma;
+};
+
struct hns_roce_dev;
struct hns_roce_qp {
@@ -424,8 +440,6 @@ struct hns_roce_ib_iboe {
struct net_device *netdevs[HNS_ROCE_MAX_PORTS];
struct notifier_block nb;
struct notifier_block nb_inet;
- /* 16 GID is shared by 6 port in v1 engine. */
- union ib_gid gid_table[HNS_ROCE_MAX_GID_NUM];
u8 phy_port[HNS_ROCE_MAX_PORTS];
};
@@ -519,6 +533,8 @@ struct hns_roce_hw {
struct ib_recv_wr **bad_recv_wr);
int (*req_notify_cq)(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+ int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr);
+ int (*destroy_cq)(struct ib_cq *ibcq);
void *priv;
};
@@ -553,6 +569,8 @@ struct hns_roce_dev {
int cmd_mod;
int loop_idc;
+ dma_addr_t tptr_dma_addr; /*only for hw v1*/
+ u32 tptr_size; /*only for hw v1*/
struct hns_roce_hw *hw;
};
@@ -657,7 +675,8 @@ void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev);
void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev);
int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj);
-void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj);
+void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj,
+ int rr);
int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
u32 reserved_bot, u32 resetrved_top);
void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap);
@@ -665,9 +684,11 @@ void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev);
int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
int align, unsigned long *obj);
void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
- unsigned long obj, int cnt);
+ unsigned long obj, int cnt,
+ int rr);
-struct ib_ah *hns_roce_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
+struct ib_ah *hns_roce_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata);
int hns_roce_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
int hns_roce_destroy_ah(struct ib_ah *ah);
@@ -681,6 +702,10 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
u64 virt_addr, int access_flags,
struct ib_udata *udata);
int hns_roce_dereg_mr(struct ib_mr *ibmr);
+int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmd_mailbox *mailbox,
+ unsigned long mpt_index);
+unsigned long key_to_hw_index(u32 key);
void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
struct hns_roce_buf *buf);
@@ -717,6 +742,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
struct ib_udata *udata);
int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq);
+void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq);
void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);
void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type);
diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c b/drivers/infiniband/hw/hns/hns_roce_eq.c
index 21e21b03cfb5..50f864935a0e 100644
--- a/drivers/infiniband/hw/hns/hns_roce_eq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_eq.c
@@ -371,9 +371,9 @@ static int hns_roce_aeq_ovf_int(struct hns_roce_dev *hr_dev,
int i = 0;
/**
- * AEQ overflow ECC mult bit err CEQ overflow alarm
- * must clear interrupt, mask irq, clear irq, cancel mask operation
- */
+ * AEQ overflow ECC mult bit err CEQ overflow alarm
+ * must clear interrupt, mask irq, clear irq, cancel mask operation
+ */
aeshift_val = roce_read(hr_dev, ROCEE_CAEP_AEQC_AEQE_SHIFT_REG);
if (roce_get_bit(aeshift_val,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
index 250d8f280390..c5104e0b2916 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
@@ -80,9 +80,9 @@ struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev, int npages,
--order;
/*
- * Alloc memory one time. If failed, don't alloc small block
- * memory, directly return fail.
- */
+ * Alloc memory one time. If failed, don't alloc small block
+ * memory, directly return fail.
+ */
mem = &chunk->mem[chunk->npages];
buf = dma_alloc_coherent(&hr_dev->pdev->dev, PAGE_SIZE << order,
&sg_dma_address(mem), gfp_mask);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 71232e5fabf6..b8111b0c8877 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -32,6 +32,7 @@
#include <linux/platform_device.h>
#include <linux/acpi.h>
+#include <linux/etherdevice.h>
#include <rdma/ib_umem.h>
#include "hns_roce_common.h"
#include "hns_roce_device.h"
@@ -72,6 +73,8 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
int nreq = 0;
u32 ind = 0;
int ret = 0;
+ u8 *smac;
+ int loopback;
if (unlikely(ibqp->qp_type != IB_QPT_GSI &&
ibqp->qp_type != IB_QPT_RC)) {
@@ -129,6 +132,14 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
UD_SEND_WQE_U32_8_DMAC_5_M,
UD_SEND_WQE_U32_8_DMAC_5_S,
ah->av.mac[5]);
+
+ smac = (u8 *)hr_dev->dev_addr[qp->port];
+ loopback = ether_addr_equal_unaligned(ah->av.mac,
+ smac) ? 1 : 0;
+ roce_set_bit(ud_sq_wqe->u32_8,
+ UD_SEND_WQE_U32_8_LOOPBACK_INDICATOR_S,
+ loopback);
+
roce_set_field(ud_sq_wqe->u32_8,
UD_SEND_WQE_U32_8_OPERATION_TYPE_M,
UD_SEND_WQE_U32_8_OPERATION_TYPE_S,
@@ -284,6 +295,8 @@ out:
roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_SQ_HEAD_M,
SQ_DOORBELL_U32_4_SQ_HEAD_S,
(qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)));
+ roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_SL_M,
+ SQ_DOORBELL_U32_4_SL_S, qp->sl);
roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_PORT_M,
SQ_DOORBELL_U32_4_PORT_S, qp->phy_port);
roce_set_field(sq_db.u32_8, SQ_DOORBELL_U32_8_QPN_M,
@@ -611,6 +624,213 @@ ext_sdb_buf_fail_out:
return ret;
}
+static struct hns_roce_qp *hns_roce_v1_create_lp_qp(struct hns_roce_dev *hr_dev,
+ struct ib_pd *pd)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct ib_qp_init_attr init_attr;
+ struct ib_qp *qp;
+
+ memset(&init_attr, 0, sizeof(struct ib_qp_init_attr));
+ init_attr.qp_type = IB_QPT_RC;
+ init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
+ init_attr.cap.max_recv_wr = HNS_ROCE_MIN_WQE_NUM;
+ init_attr.cap.max_send_wr = HNS_ROCE_MIN_WQE_NUM;
+
+ qp = hns_roce_create_qp(pd, &init_attr, NULL);
+ if (IS_ERR(qp)) {
+ dev_err(dev, "Create loop qp for mr free failed!");
+ return NULL;
+ }
+
+ return to_hr_qp(qp);
+}
+
+static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_caps *caps = &hr_dev->caps;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct ib_cq_init_attr cq_init_attr;
+ struct hns_roce_free_mr *free_mr;
+ struct ib_qp_attr attr = { 0 };
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_qp *hr_qp;
+ struct ib_cq *cq;
+ struct ib_pd *pd;
+ u64 subnet_prefix;
+ int attr_mask = 0;
+ int i;
+ int ret;
+ u8 phy_port;
+ u8 sl;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+
+ /* Reserved cq for loop qp */
+ cq_init_attr.cqe = HNS_ROCE_MIN_WQE_NUM * 2;
+ cq_init_attr.comp_vector = 0;
+ cq = hns_roce_ib_create_cq(&hr_dev->ib_dev, &cq_init_attr, NULL, NULL);
+ if (IS_ERR(cq)) {
+ dev_err(dev, "Create cq for reseved loop qp failed!");
+ return -ENOMEM;
+ }
+ free_mr->mr_free_cq = to_hr_cq(cq);
+ free_mr->mr_free_cq->ib_cq.device = &hr_dev->ib_dev;
+ free_mr->mr_free_cq->ib_cq.uobject = NULL;
+ free_mr->mr_free_cq->ib_cq.comp_handler = NULL;
+ free_mr->mr_free_cq->ib_cq.event_handler = NULL;
+ free_mr->mr_free_cq->ib_cq.cq_context = NULL;
+ atomic_set(&free_mr->mr_free_cq->ib_cq.usecnt, 0);
+
+ pd = hns_roce_alloc_pd(&hr_dev->ib_dev, NULL, NULL);
+ if (IS_ERR(pd)) {
+ dev_err(dev, "Create pd for reseved loop qp failed!");
+ ret = -ENOMEM;
+ goto alloc_pd_failed;
+ }
+ free_mr->mr_free_pd = to_hr_pd(pd);
+ free_mr->mr_free_pd->ibpd.device = &hr_dev->ib_dev;
+ free_mr->mr_free_pd->ibpd.uobject = NULL;
+ atomic_set(&free_mr->mr_free_pd->ibpd.usecnt, 0);
+
+ attr.qp_access_flags = IB_ACCESS_REMOTE_WRITE;
+ attr.pkey_index = 0;
+ attr.min_rnr_timer = 0;
+ /* Disable read ability */
+ attr.max_dest_rd_atomic = 0;
+ attr.max_rd_atomic = 0;
+ /* Use arbitrary values as rq_psn and sq_psn */
+ attr.rq_psn = 0x0808;
+ attr.sq_psn = 0x0808;
+ attr.retry_cnt = 7;
+ attr.rnr_retry = 7;
+ attr.timeout = 0x12;
+ attr.path_mtu = IB_MTU_256;
+ attr.ah_attr.ah_flags = 1;
+ attr.ah_attr.static_rate = 3;
+ attr.ah_attr.grh.sgid_index = 0;
+ attr.ah_attr.grh.hop_limit = 1;
+ attr.ah_attr.grh.flow_label = 0;
+ attr.ah_attr.grh.traffic_class = 0;
+
+ subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
+ for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
+ free_mr->mr_free_qp[i] = hns_roce_v1_create_lp_qp(hr_dev, pd);
+ if (IS_ERR(free_mr->mr_free_qp[i])) {
+ dev_err(dev, "Create loop qp failed!\n");
+ goto create_lp_qp_failed;
+ }
+ hr_qp = free_mr->mr_free_qp[i];
+
+ sl = i / caps->num_ports;
+
+ if (caps->num_ports == HNS_ROCE_MAX_PORTS)
+ phy_port = (i >= HNS_ROCE_MAX_PORTS) ? (i - 2) :
+ (i % caps->num_ports);
+ else
+ phy_port = i % caps->num_ports;
+
+ hr_qp->port = phy_port + 1;
+ hr_qp->phy_port = phy_port;
+ hr_qp->ibqp.qp_type = IB_QPT_RC;
+ hr_qp->ibqp.device = &hr_dev->ib_dev;
+ hr_qp->ibqp.uobject = NULL;
+ atomic_set(&hr_qp->ibqp.usecnt, 0);
+ hr_qp->ibqp.pd = pd;
+ hr_qp->ibqp.recv_cq = cq;
+ hr_qp->ibqp.send_cq = cq;
+
+ attr.ah_attr.port_num = phy_port + 1;
+ attr.ah_attr.sl = sl;
+ attr.port_num = phy_port + 1;
+
+ attr.dest_qp_num = hr_qp->qpn;
+ memcpy(attr.ah_attr.dmac, hr_dev->dev_addr[phy_port],
+ MAC_ADDR_OCTET_NUM);
+
+ memcpy(attr.ah_attr.grh.dgid.raw,
+ &subnet_prefix, sizeof(u64));
+ memcpy(&attr.ah_attr.grh.dgid.raw[8],
+ hr_dev->dev_addr[phy_port], 3);
+ memcpy(&attr.ah_attr.grh.dgid.raw[13],
+ hr_dev->dev_addr[phy_port] + 3, 3);
+ attr.ah_attr.grh.dgid.raw[11] = 0xff;
+ attr.ah_attr.grh.dgid.raw[12] = 0xfe;
+ attr.ah_attr.grh.dgid.raw[8] ^= 2;
+
+ attr_mask |= IB_QP_PORT;
+
+ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, &attr, attr_mask,
+ IB_QPS_RESET, IB_QPS_INIT);
+ if (ret) {
+ dev_err(dev, "modify qp failed(%d)!\n", ret);
+ goto create_lp_qp_failed;
+ }
+
+ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, &attr, attr_mask,
+ IB_QPS_INIT, IB_QPS_RTR);
+ if (ret) {
+ dev_err(dev, "modify qp failed(%d)!\n", ret);
+ goto create_lp_qp_failed;
+ }
+
+ ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, &attr, attr_mask,
+ IB_QPS_RTR, IB_QPS_RTS);
+ if (ret) {
+ dev_err(dev, "modify qp failed(%d)!\n", ret);
+ goto create_lp_qp_failed;
+ }
+ }
+
+ return 0;
+
+create_lp_qp_failed:
+ for (i -= 1; i >= 0; i--) {
+ hr_qp = free_mr->mr_free_qp[i];
+ if (hns_roce_v1_destroy_qp(&hr_qp->ibqp))
+ dev_err(dev, "Destroy qp %d for mr free failed!\n", i);
+ }
+
+ if (hns_roce_dealloc_pd(pd))
+ dev_err(dev, "Destroy pd for create_lp_qp failed!\n");
+
+alloc_pd_failed:
+ if (hns_roce_ib_destroy_cq(cq))
+ dev_err(dev, "Destroy cq for create_lp_qp failed!\n");
+
+ return -EINVAL;
+}
+
+static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_free_mr *free_mr;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_qp *hr_qp;
+ int ret;
+ int i;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+
+ for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
+ hr_qp = free_mr->mr_free_qp[i];
+ ret = hns_roce_v1_destroy_qp(&hr_qp->ibqp);
+ if (ret)
+ dev_err(dev, "Destroy qp %d for mr free failed(%d)!\n",
+ i, ret);
+ }
+
+ ret = hns_roce_ib_destroy_cq(&free_mr->mr_free_cq->ib_cq);
+ if (ret)
+ dev_err(dev, "Destroy cq for mr_free failed(%d)!\n", ret);
+
+ ret = hns_roce_dealloc_pd(&free_mr->mr_free_pd->ibpd);
+ if (ret)
+ dev_err(dev, "Destroy pd for mr_free failed(%d)!\n", ret);
+}
+
static int hns_roce_db_init(struct hns_roce_dev *hr_dev)
{
struct device *dev = &hr_dev->pdev->dev;
@@ -648,6 +868,223 @@ static int hns_roce_db_init(struct hns_roce_dev *hr_dev)
return 0;
}
+void hns_roce_v1_recreate_lp_qp_work_fn(struct work_struct *work)
+{
+ struct hns_roce_recreate_lp_qp_work *lp_qp_work;
+ struct hns_roce_dev *hr_dev;
+
+ lp_qp_work = container_of(work, struct hns_roce_recreate_lp_qp_work,
+ work);
+ hr_dev = to_hr_dev(lp_qp_work->ib_dev);
+
+ hns_roce_v1_release_lp_qp(hr_dev);
+
+ if (hns_roce_v1_rsv_lp_qp(hr_dev))
+ dev_err(&hr_dev->pdev->dev, "create reserver qp failed\n");
+
+ if (lp_qp_work->comp_flag)
+ complete(lp_qp_work->comp);
+
+ kfree(lp_qp_work);
+}
+
+static int hns_roce_v1_recreate_lp_qp(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_recreate_lp_qp_work *lp_qp_work;
+ struct hns_roce_free_mr *free_mr;
+ struct hns_roce_v1_priv *priv;
+ struct completion comp;
+ unsigned long end =
+ msecs_to_jiffies(HNS_ROCE_V1_RECREATE_LP_QP_TIMEOUT_MSECS) + jiffies;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+
+ lp_qp_work = kzalloc(sizeof(struct hns_roce_recreate_lp_qp_work),
+ GFP_KERNEL);
+
+ INIT_WORK(&(lp_qp_work->work), hns_roce_v1_recreate_lp_qp_work_fn);
+
+ lp_qp_work->ib_dev = &(hr_dev->ib_dev);
+ lp_qp_work->comp = &comp;
+ lp_qp_work->comp_flag = 1;
+
+ init_completion(lp_qp_work->comp);
+
+ queue_work(free_mr->free_mr_wq, &(lp_qp_work->work));
+
+ while (time_before_eq(jiffies, end)) {
+ if (try_wait_for_completion(&comp))
+ return 0;
+ msleep(HNS_ROCE_V1_RECREATE_LP_QP_WAIT_VALUE);
+ }
+
+ lp_qp_work->comp_flag = 0;
+ if (try_wait_for_completion(&comp))
+ return 0;
+
+ dev_warn(dev, "recreate lp qp failed 20s timeout and return failed!\n");
+ return -ETIMEDOUT;
+}
+
+static int hns_roce_v1_send_lp_wqe(struct hns_roce_qp *hr_qp)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(hr_qp->ibqp.device);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct ib_send_wr send_wr, *bad_wr;
+ int ret;
+
+ memset(&send_wr, 0, sizeof(send_wr));
+ send_wr.next = NULL;
+ send_wr.num_sge = 0;
+ send_wr.send_flags = 0;
+ send_wr.sg_list = NULL;
+ send_wr.wr_id = (unsigned long long)&send_wr;
+ send_wr.opcode = IB_WR_RDMA_WRITE;
+
+ ret = hns_roce_v1_post_send(&hr_qp->ibqp, &send_wr, &bad_wr);
+ if (ret) {
+ dev_err(dev, "Post write wqe for mr free failed(%d)!", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
+{
+ struct hns_roce_mr_free_work *mr_work;
+ struct ib_wc wc[HNS_ROCE_V1_RESV_QP];
+ struct hns_roce_free_mr *free_mr;
+ struct hns_roce_cq *mr_free_cq;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_dev *hr_dev;
+ struct hns_roce_mr *hr_mr;
+ struct hns_roce_qp *hr_qp;
+ struct device *dev;
+ unsigned long end =
+ msecs_to_jiffies(HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS) + jiffies;
+ int i;
+ int ret;
+ int ne;
+
+ mr_work = container_of(work, struct hns_roce_mr_free_work, work);
+ hr_mr = (struct hns_roce_mr *)mr_work->mr;
+ hr_dev = to_hr_dev(mr_work->ib_dev);
+ dev = &hr_dev->pdev->dev;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+ mr_free_cq = free_mr->mr_free_cq;
+
+ for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
+ hr_qp = free_mr->mr_free_qp[i];
+ ret = hns_roce_v1_send_lp_wqe(hr_qp);
+ if (ret) {
+ dev_err(dev,
+ "Send wqe (qp:0x%lx) for mr free failed(%d)!\n",
+ hr_qp->qpn, ret);
+ goto free_work;
+ }
+ }
+
+ ne = HNS_ROCE_V1_RESV_QP;
+ do {
+ ret = hns_roce_v1_poll_cq(&mr_free_cq->ib_cq, ne, wc);
+ if (ret < 0) {
+ dev_err(dev,
+ "(qp:0x%lx) starts, Poll cqe failed(%d) for mr 0x%x free! Remain %d cqe\n",
+ hr_qp->qpn, ret, hr_mr->key, ne);
+ goto free_work;
+ }
+ ne -= ret;
+ msleep(HNS_ROCE_V1_FREE_MR_WAIT_VALUE);
+ } while (ne && time_before_eq(jiffies, end));
+
+ if (ne != 0)
+ dev_err(dev,
+ "Poll cqe for mr 0x%x free timeout! Remain %d cqe\n",
+ hr_mr->key, ne);
+
+free_work:
+ if (mr_work->comp_flag)
+ complete(mr_work->comp);
+ kfree(mr_work);
+}
+
+int hns_roce_v1_dereg_mr(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_mr_free_work *mr_work;
+ struct hns_roce_free_mr *free_mr;
+ struct hns_roce_v1_priv *priv;
+ struct completion comp;
+ unsigned long end =
+ msecs_to_jiffies(HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS) + jiffies;
+ unsigned long start = jiffies;
+ int npages;
+ int ret = 0;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+
+ if (mr->enabled) {
+ if (hns_roce_hw2sw_mpt(hr_dev, NULL, key_to_hw_index(mr->key)
+ & (hr_dev->caps.num_mtpts - 1)))
+ dev_warn(dev, "HW2SW_MPT failed!\n");
+ }
+
+ mr_work = kzalloc(sizeof(*mr_work), GFP_KERNEL);
+ if (!mr_work) {
+ ret = -ENOMEM;
+ goto free_mr;
+ }
+
+ INIT_WORK(&(mr_work->work), hns_roce_v1_mr_free_work_fn);
+
+ mr_work->ib_dev = &(hr_dev->ib_dev);
+ mr_work->comp = &comp;
+ mr_work->comp_flag = 1;
+ mr_work->mr = (void *)mr;
+ init_completion(mr_work->comp);
+
+ queue_work(free_mr->free_mr_wq, &(mr_work->work));
+
+ while (time_before_eq(jiffies, end)) {
+ if (try_wait_for_completion(&comp))
+ goto free_mr;
+ msleep(HNS_ROCE_V1_FREE_MR_WAIT_VALUE);
+ }
+
+ mr_work->comp_flag = 0;
+ if (try_wait_for_completion(&comp))
+ goto free_mr;
+
+ dev_warn(dev, "Free mr work 0x%x over 50s and failed!\n", mr->key);
+ ret = -ETIMEDOUT;
+
+free_mr:
+ dev_dbg(dev, "Free mr 0x%x use 0x%x us.\n",
+ mr->key, jiffies_to_usecs(jiffies) - jiffies_to_usecs(start));
+
+ if (mr->size != ~0ULL) {
+ npages = ib_umem_page_count(mr->umem);
+ dma_free_coherent(dev, npages * 8, mr->pbl_buf,
+ mr->pbl_dma_addr);
+ }
+
+ hns_roce_bitmap_free(&hr_dev->mr_table.mtpt_bitmap,
+ key_to_hw_index(mr->key), 0);
+
+ if (mr->umem)
+ ib_umem_release(mr->umem);
+
+ kfree(mr);
+
+ return ret;
+}
+
static void hns_roce_db_free(struct hns_roce_dev *hr_dev)
{
struct device *dev = &hr_dev->pdev->dev;
@@ -849,6 +1286,85 @@ static void hns_roce_bt_free(struct hns_roce_dev *hr_dev)
priv->bt_table.qpc_buf.buf, priv->bt_table.qpc_buf.map);
}
+static int hns_roce_tptr_init(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_buf_list *tptr_buf;
+ struct hns_roce_v1_priv *priv;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ tptr_buf = &priv->tptr_table.tptr_buf;
+
+ /*
+ * This buffer will be used for CQ's tptr(tail pointer), also
+ * named ci(customer index). Every CQ will use 2 bytes to save
+ * cqe ci in hip06. Hardware will read this area to get new ci
+ * when the queue is almost full.
+ */
+ tptr_buf->buf = dma_alloc_coherent(dev, HNS_ROCE_V1_TPTR_BUF_SIZE,
+ &tptr_buf->map, GFP_KERNEL);
+ if (!tptr_buf->buf)
+ return -ENOMEM;
+
+ hr_dev->tptr_dma_addr = tptr_buf->map;
+ hr_dev->tptr_size = HNS_ROCE_V1_TPTR_BUF_SIZE;
+
+ return 0;
+}
+
+static void hns_roce_tptr_free(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_buf_list *tptr_buf;
+ struct hns_roce_v1_priv *priv;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ tptr_buf = &priv->tptr_table.tptr_buf;
+
+ dma_free_coherent(dev, HNS_ROCE_V1_TPTR_BUF_SIZE,
+ tptr_buf->buf, tptr_buf->map);
+}
+
+static int hns_roce_free_mr_init(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_free_mr *free_mr;
+ struct hns_roce_v1_priv *priv;
+ int ret = 0;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+
+ free_mr->free_mr_wq = create_singlethread_workqueue("hns_roce_free_mr");
+ if (!free_mr->free_mr_wq) {
+ dev_err(dev, "Create free mr workqueue failed!\n");
+ return -ENOMEM;
+ }
+
+ ret = hns_roce_v1_rsv_lp_qp(hr_dev);
+ if (ret) {
+ dev_err(dev, "Reserved loop qp failed(%d)!\n", ret);
+ flush_workqueue(free_mr->free_mr_wq);
+ destroy_workqueue(free_mr->free_mr_wq);
+ }
+
+ return ret;
+}
+
+static void hns_roce_free_mr_free(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_free_mr *free_mr;
+ struct hns_roce_v1_priv *priv;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ free_mr = &priv->free_mr;
+
+ flush_workqueue(free_mr->free_mr_wq);
+ destroy_workqueue(free_mr->free_mr_wq);
+
+ hns_roce_v1_release_lp_qp(hr_dev);
+}
+
/**
* hns_roce_v1_reset - reset RoCE
* @hr_dev: RoCE device struct pointer
@@ -898,6 +1414,38 @@ int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset)
return ret;
}
+static int hns_roce_des_qp_init(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_des_qp *des_qp;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ des_qp = &priv->des_qp;
+
+ des_qp->requeue_flag = 1;
+ des_qp->qp_wq = create_singlethread_workqueue("hns_roce_destroy_qp");
+ if (!des_qp->qp_wq) {
+ dev_err(dev, "Create destroy qp workqueue failed!\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void hns_roce_des_qp_free(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_des_qp *des_qp;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ des_qp = &priv->des_qp;
+
+ des_qp->requeue_flag = 0;
+ flush_workqueue(des_qp->qp_wq);
+ destroy_workqueue(des_qp->qp_wq);
+}
+
void hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
{
int i = 0;
@@ -906,12 +1454,11 @@ void hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
hr_dev->vendor_id = le32_to_cpu(roce_read(hr_dev, ROCEE_VENDOR_ID_REG));
hr_dev->vendor_part_id = le32_to_cpu(roce_read(hr_dev,
ROCEE_VENDOR_PART_ID_REG));
- hr_dev->hw_rev = le32_to_cpu(roce_read(hr_dev, ROCEE_HW_VERSION_REG));
-
hr_dev->sys_image_guid = le32_to_cpu(roce_read(hr_dev,
ROCEE_SYS_IMAGE_GUID_L_REG)) |
((u64)le32_to_cpu(roce_read(hr_dev,
ROCEE_SYS_IMAGE_GUID_H_REG)) << 32);
+ hr_dev->hw_rev = HNS_ROCE_HW_VER1;
caps->num_qps = HNS_ROCE_V1_MAX_QP_NUM;
caps->max_wqes = HNS_ROCE_V1_MAX_WQE_NUM;
@@ -1001,18 +1548,44 @@ int hns_roce_v1_init(struct hns_roce_dev *hr_dev)
goto error_failed_raq_init;
}
- hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_UP);
-
ret = hns_roce_bt_init(hr_dev);
if (ret) {
dev_err(dev, "bt init failed!\n");
goto error_failed_bt_init;
}
+ ret = hns_roce_tptr_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "tptr init failed!\n");
+ goto error_failed_tptr_init;
+ }
+
+ ret = hns_roce_des_qp_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "des qp init failed!\n");
+ goto error_failed_des_qp_init;
+ }
+
+ ret = hns_roce_free_mr_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "free mr init failed!\n");
+ goto error_failed_free_mr_init;
+ }
+
+ hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_UP);
+
return 0;
+error_failed_free_mr_init:
+ hns_roce_des_qp_free(hr_dev);
+
+error_failed_des_qp_init:
+ hns_roce_tptr_free(hr_dev);
+
+error_failed_tptr_init:
+ hns_roce_bt_free(hr_dev);
+
error_failed_bt_init:
- hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
hns_roce_raq_free(hr_dev);
error_failed_raq_init:
@@ -1022,8 +1595,11 @@ error_failed_raq_init:
void hns_roce_v1_exit(struct hns_roce_dev *hr_dev)
{
- hns_roce_bt_free(hr_dev);
hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
+ hns_roce_free_mr_free(hr_dev);
+ hns_roce_des_qp_free(hr_dev);
+ hns_roce_tptr_free(hr_dev);
+ hns_roce_bt_free(hr_dev);
hns_roce_raq_free(hr_dev);
hns_roce_db_free(hr_dev);
}
@@ -1061,6 +1637,14 @@ void hns_roce_v1_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr)
u32 *p;
u32 val;
+ /*
+ * When mac changed, loopback may fail
+ * because of smac not equal to dmac.
+ * We Need to release and create reserved qp again.
+ */
+ if (hr_dev->hw->dereg_mr && hns_roce_v1_recreate_lp_qp(hr_dev))
+ dev_warn(&hr_dev->pdev->dev, "recreate lp qp timeout!\n");
+
p = (u32 *)(&addr[0]);
reg_smac_l = *p;
roce_raw_write(reg_smac_l, hr_dev->reg_base + ROCEE_SMAC_L_0_REG +
@@ -1293,9 +1877,9 @@ static void __hns_roce_v1_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn,
}
/*
- * Now backwards through the CQ, removing CQ entries
- * that match our QP by overwriting them with next entries.
- */
+ * Now backwards through the CQ, removing CQ entries
+ * that match our QP by overwriting them with next entries.
+ */
while ((int) --prod_index - (int) hr_cq->cons_index >= 0) {
cqe = get_cqe(hr_cq, prod_index & hr_cq->ib_cq.cqe);
if ((roce_get_field(cqe->cqe_byte_16, CQE_BYTE_16_LOCAL_QPN_M,
@@ -1317,9 +1901,9 @@ static void __hns_roce_v1_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn,
if (nfreed) {
hr_cq->cons_index += nfreed;
/*
- * Make sure update of buffer contents is done before
- * updating consumer index.
- */
+ * Make sure update of buffer contents is done before
+ * updating consumer index.
+ */
wmb();
hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index);
@@ -1339,14 +1923,21 @@ void hns_roce_v1_write_cqc(struct hns_roce_dev *hr_dev,
dma_addr_t dma_handle, int nent, u32 vector)
{
struct hns_roce_cq_context *cq_context = NULL;
- void __iomem *tptr_addr;
+ struct hns_roce_buf_list *tptr_buf;
+ struct hns_roce_v1_priv *priv;
+ dma_addr_t tptr_dma_addr;
+ int offset;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ tptr_buf = &priv->tptr_table.tptr_buf;
cq_context = mb_buf;
memset(cq_context, 0, sizeof(*cq_context));
- tptr_addr = 0;
- hr_dev->priv_addr = tptr_addr;
- hr_cq->tptr_addr = tptr_addr;
+ /* Get the tptr for this CQ. */
+ offset = hr_cq->cqn * HNS_ROCE_V1_TPTR_ENTRY_SIZE;
+ tptr_dma_addr = tptr_buf->map + offset;
+ hr_cq->tptr_addr = (u16 *)(tptr_buf->buf + offset);
/* Register cq_context members */
roce_set_field(cq_context->cqc_byte_4,
@@ -1390,10 +1981,10 @@ void hns_roce_v1_write_cqc(struct hns_roce_dev *hr_dev,
roce_set_field(cq_context->cqc_byte_20,
CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_M,
CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_S,
- (u64)tptr_addr >> 44);
+ tptr_dma_addr >> 44);
cq_context->cqc_byte_20 = cpu_to_le32(cq_context->cqc_byte_20);
- cq_context->cqe_tptr_addr_l = (u32)((u64)tptr_addr >> 12);
+ cq_context->cqe_tptr_addr_l = (u32)(tptr_dma_addr >> 12);
roce_set_field(cq_context->cqc_byte_32,
CQ_CONTEXT_CQC_BYTE_32_CUR_CQE_BA1_H_M,
@@ -1407,7 +1998,7 @@ void hns_roce_v1_write_cqc(struct hns_roce_dev *hr_dev,
roce_set_bit(cq_context->cqc_byte_32,
CQ_CQNTEXT_CQC_BYTE_32_TYPE_OF_COMPLETION_NOTIFICATION_S,
0);
- /*The initial value of cq's ci is 0 */
+ /* The initial value of cq's ci is 0 */
roce_set_field(cq_context->cqc_byte_32,
CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_M,
CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S, 0);
@@ -1424,9 +2015,9 @@ int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
notification_flag = (flags & IB_CQ_SOLICITED_MASK) ==
IB_CQ_SOLICITED ? CQ_DB_REQ_NOT : CQ_DB_REQ_NOT_SOL;
/*
- * flags = 0; Notification Flag = 1, next
- * flags = 1; Notification Flag = 0, solocited
- */
+ * flags = 0; Notification Flag = 1, next
+ * flags = 1; Notification Flag = 0, solocited
+ */
doorbell[0] = hr_cq->cons_index & ((hr_cq->cq_depth << 1) - 1);
roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M,
@@ -1581,10 +2172,10 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
wq = &(*cur_qp)->sq;
if ((*cur_qp)->sq_signal_bits) {
/*
- * If sg_signal_bit is 1,
- * firstly tail pointer updated to wqe
- * which current cqe correspond to
- */
+ * If sg_signal_bit is 1,
+ * firstly tail pointer updated to wqe
+ * which current cqe correspond to
+ */
wqe_ctr = (u16)roce_get_field(cqe->cqe_byte_4,
CQE_BYTE_4_WQE_INDEX_M,
CQE_BYTE_4_WQE_INDEX_S);
@@ -1659,8 +2250,14 @@ int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
break;
}
- if (npolled)
+ if (npolled) {
+ *hr_cq->tptr_addr = hr_cq->cons_index &
+ ((hr_cq->cq_depth << 1) - 1);
+
+ /* Memroy barrier */
+ wmb();
hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index);
+ }
spin_unlock_irqrestore(&hr_cq->lock, flags);
@@ -1799,12 +2396,12 @@ static int hns_roce_v1_qp_modify(struct hns_roce_dev *hr_dev,
if (op[cur_state][new_state] == HNS_ROCE_CMD_2RST_QP)
return hns_roce_cmd_mbox(hr_dev, 0, 0, hr_qp->qpn, 2,
HNS_ROCE_CMD_2RST_QP,
- HNS_ROCE_CMD_TIME_CLASS_A);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
if (op[cur_state][new_state] == HNS_ROCE_CMD_2ERR_QP)
return hns_roce_cmd_mbox(hr_dev, 0, 0, hr_qp->qpn, 2,
HNS_ROCE_CMD_2ERR_QP,
- HNS_ROCE_CMD_TIME_CLASS_A);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
if (IS_ERR(mailbox))
@@ -1814,7 +2411,7 @@ static int hns_roce_v1_qp_modify(struct hns_roce_dev *hr_dev,
ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, hr_qp->qpn, 0,
op[cur_state][new_state],
- HNS_ROCE_CMD_TIME_CLASS_C);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
return ret;
@@ -2000,11 +2597,11 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
}
/*
- *Reset to init
- * Mandatory param:
- * IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS
- * Optional param: NA
- */
+ * Reset to init
+ * Mandatory param:
+ * IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS
+ * Optional param: NA
+ */
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
roce_set_field(context->qpc_bytes_4,
QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_M,
@@ -2172,24 +2769,14 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
QP_CONTEXT_QPC_BYTE_32_SIGNALING_TYPE_S,
hr_qp->sq_signal_bits);
- for (port = 0; port < hr_dev->caps.num_ports; port++) {
- smac = (u8 *)hr_dev->dev_addr[port];
- dev_dbg(dev, "smac: %2x: %2x: %2x: %2x: %2x: %2x\n",
- smac[0], smac[1], smac[2], smac[3], smac[4],
- smac[5]);
- if ((dmac[0] == smac[0]) && (dmac[1] == smac[1]) &&
- (dmac[2] == smac[2]) && (dmac[3] == smac[3]) &&
- (dmac[4] == smac[4]) && (dmac[5] == smac[5])) {
- roce_set_bit(context->qpc_bytes_32,
- QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S,
- 1);
- break;
- }
- }
-
- if (hr_dev->loop_idc == 0x1)
+ port = (attr_mask & IB_QP_PORT) ? (attr->port_num - 1) :
+ hr_qp->port;
+ smac = (u8 *)hr_dev->dev_addr[port];
+ /* when dmac equals smac or loop_idc is 1, it should loopback */
+ if (ether_addr_equal_unaligned(dmac, smac) ||
+ hr_dev->loop_idc == 0x1)
roce_set_bit(context->qpc_bytes_32,
- QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S, 1);
+ QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S, 1);
roce_set_bit(context->qpc_bytes_32,
QP_CONTEXT_QPC_BYTE_32_GLOBAL_HEADER_S,
@@ -2509,7 +3096,7 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
/* Every status migrate must change state */
roce_set_field(context->qpc_bytes_144,
QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
- QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, attr->qp_state);
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, new_state);
/* SW pass context to HW */
ret = hns_roce_v1_qp_modify(hr_dev, &hr_qp->mtt,
@@ -2522,9 +3109,9 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
}
/*
- * Use rst2init to instead of init2init with drv,
- * need to hw to flash RQ HEAD by DB again
- */
+ * Use rst2init to instead of init2init with drv,
+ * need to hw to flash RQ HEAD by DB again
+ */
if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
/* Memory barrier */
wmb();
@@ -2619,7 +3206,7 @@ static int hns_roce_v1_query_qpc(struct hns_roce_dev *hr_dev,
ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, hr_qp->qpn, 0,
HNS_ROCE_CMD_QUERY_QP,
- HNS_ROCE_CMD_TIME_CLASS_A);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
if (!ret)
memcpy(hr_context, mailbox->buf, sizeof(*hr_context));
else
@@ -2630,8 +3217,78 @@ static int hns_roce_v1_query_qpc(struct hns_roce_dev *hr_dev,
return ret;
}
-int hns_roce_v1_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 hns_roce_v1_q_sqp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask,
+ struct ib_qp_init_attr *qp_init_attr)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct hns_roce_sqp_context context;
+ u32 addr;
+
+ mutex_lock(&hr_qp->mutex);
+
+ if (hr_qp->state == IB_QPS_RESET) {
+ qp_attr->qp_state = IB_QPS_RESET;
+ goto done;
+ }
+
+ addr = ROCEE_QP1C_CFG0_0_REG +
+ hr_qp->port * sizeof(struct hns_roce_sqp_context);
+ context.qp1c_bytes_4 = roce_read(hr_dev, addr);
+ context.sq_rq_bt_l = roce_read(hr_dev, addr + 1);
+ context.qp1c_bytes_12 = roce_read(hr_dev, addr + 2);
+ context.qp1c_bytes_16 = roce_read(hr_dev, addr + 3);
+ context.qp1c_bytes_20 = roce_read(hr_dev, addr + 4);
+ context.cur_rq_wqe_ba_l = roce_read(hr_dev, addr + 5);
+ context.qp1c_bytes_28 = roce_read(hr_dev, addr + 6);
+ context.qp1c_bytes_32 = roce_read(hr_dev, addr + 7);
+ context.cur_sq_wqe_ba_l = roce_read(hr_dev, addr + 8);
+ context.qp1c_bytes_40 = roce_read(hr_dev, addr + 9);
+
+ hr_qp->state = roce_get_field(context.qp1c_bytes_4,
+ QP1C_BYTES_4_QP_STATE_M,
+ QP1C_BYTES_4_QP_STATE_S);
+ qp_attr->qp_state = hr_qp->state;
+ qp_attr->path_mtu = IB_MTU_256;
+ qp_attr->path_mig_state = IB_MIG_ARMED;
+ qp_attr->qkey = QKEY_VAL;
+ qp_attr->rq_psn = 0;
+ qp_attr->sq_psn = 0;
+ qp_attr->dest_qp_num = 1;
+ qp_attr->qp_access_flags = 6;
+
+ qp_attr->pkey_index = roce_get_field(context.qp1c_bytes_20,
+ QP1C_BYTES_20_PKEY_IDX_M,
+ QP1C_BYTES_20_PKEY_IDX_S);
+ qp_attr->port_num = hr_qp->port + 1;
+ qp_attr->sq_draining = 0;
+ qp_attr->max_rd_atomic = 0;
+ qp_attr->max_dest_rd_atomic = 0;
+ qp_attr->min_rnr_timer = 0;
+ qp_attr->timeout = 0;
+ qp_attr->retry_cnt = 0;
+ qp_attr->rnr_retry = 0;
+ qp_attr->alt_timeout = 0;
+
+done:
+ qp_attr->cur_qp_state = qp_attr->qp_state;
+ qp_attr->cap.max_recv_wr = hr_qp->rq.wqe_cnt;
+ qp_attr->cap.max_recv_sge = hr_qp->rq.max_gs;
+ qp_attr->cap.max_send_wr = hr_qp->sq.wqe_cnt;
+ qp_attr->cap.max_send_sge = hr_qp->sq.max_gs;
+ qp_attr->cap.max_inline_data = 0;
+ qp_init_attr->cap = qp_attr->cap;
+ qp_init_attr->create_flags = 0;
+
+ mutex_unlock(&hr_qp->mutex);
+
+ return 0;
+}
+
+static int hns_roce_v1_q_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask,
+ struct ib_qp_init_attr *qp_init_attr)
{
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
@@ -2725,9 +3382,7 @@ int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
qp_attr->pkey_index = roce_get_field(context->qpc_bytes_12,
QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S);
- qp_attr->port_num = (u8)roce_get_field(context->qpc_bytes_156,
- QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
- QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S) + 1;
+ qp_attr->port_num = hr_qp->port + 1;
qp_attr->sq_draining = 0;
qp_attr->max_rd_atomic = roce_get_field(context->qpc_bytes_156,
QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_M,
@@ -2767,134 +3422,397 @@ out:
return ret;
}
-static void hns_roce_v1_destroy_qp_common(struct hns_roce_dev *hr_dev,
- struct hns_roce_qp *hr_qp,
- int is_user)
+int hns_roce_v1_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 hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+
+ return hr_qp->doorbell_qpn <= 1 ?
+ hns_roce_v1_q_sqp(ibqp, qp_attr, qp_attr_mask, qp_init_attr) :
+ hns_roce_v1_q_qp(ibqp, qp_attr, qp_attr_mask, qp_init_attr);
+}
+
+static int check_qp_db_process_status(struct hns_roce_dev *hr_dev,
+ struct hns_roce_qp *hr_qp,
+ u32 sdb_issue_ptr,
+ u32 *sdb_inv_cnt,
+ u32 *wait_stage)
{
- u32 sdbinvcnt;
- unsigned long end = 0;
- u32 sdbinvcnt_val;
- u32 sdbsendptr_val;
- u32 sdbisusepr_val;
- struct hns_roce_cq *send_cq, *recv_cq;
struct device *dev = &hr_dev->pdev->dev;
+ u32 sdb_retry_cnt, old_retry;
+ u32 sdb_send_ptr, old_send;
+ u32 success_flags = 0;
+ u32 cur_cnt, old_cnt;
+ unsigned long end;
+ u32 send_ptr;
+ u32 inv_cnt;
+ u32 tsp_st;
+
+ if (*wait_stage > HNS_ROCE_V1_DB_STAGE2 ||
+ *wait_stage < HNS_ROCE_V1_DB_STAGE1) {
+ dev_err(dev, "QP(0x%lx) db status wait stage(%d) error!\n",
+ hr_qp->qpn, *wait_stage);
+ return -EINVAL;
+ }
- if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
- if (hr_qp->state != IB_QPS_RESET) {
- /*
- * Set qp to ERR,
- * waiting for hw complete processing all dbs
- */
- if (hns_roce_v1_qp_modify(hr_dev, NULL,
- to_hns_roce_state(
- (enum ib_qp_state)hr_qp->state),
- HNS_ROCE_QP_STATE_ERR, NULL,
- hr_qp))
- dev_err(dev, "modify QP %06lx to ERR failed.\n",
- hr_qp->qpn);
-
- /* Record issued doorbell */
- sdbisusepr_val = roce_read(hr_dev,
- ROCEE_SDB_ISSUE_PTR_REG);
- /*
- * Query db process status,
- * until hw process completely
- */
- end = msecs_to_jiffies(
- HNS_ROCE_QP_DESTROY_TIMEOUT_MSECS) + jiffies;
- do {
- sdbsendptr_val = roce_read(hr_dev,
+ /* Calculate the total timeout for the entire verification process */
+ end = msecs_to_jiffies(HNS_ROCE_V1_CHECK_DB_TIMEOUT_MSECS) + jiffies;
+
+ if (*wait_stage == HNS_ROCE_V1_DB_STAGE1) {
+ /* Query db process status, until hw process completely */
+ sdb_send_ptr = roce_read(hr_dev, ROCEE_SDB_SEND_PTR_REG);
+ while (roce_hw_index_cmp_lt(sdb_send_ptr, sdb_issue_ptr,
+ ROCEE_SDB_PTR_CMP_BITS)) {
+ if (!time_before(jiffies, end)) {
+ dev_dbg(dev, "QP(0x%lx) db process stage1 timeout. issue 0x%x send 0x%x.\n",
+ hr_qp->qpn, sdb_issue_ptr,
+ sdb_send_ptr);
+ return 0;
+ }
+
+ msleep(HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS);
+ sdb_send_ptr = roce_read(hr_dev,
ROCEE_SDB_SEND_PTR_REG);
- if (!time_before(jiffies, end)) {
- dev_err(dev, "destroy qp(0x%lx) timeout!!!",
- hr_qp->qpn);
- break;
- }
- } while ((short)(roce_get_field(sdbsendptr_val,
- ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
- ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) -
- roce_get_field(sdbisusepr_val,
- ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_M,
- ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S)
- ) < 0);
+ }
- /* Get list pointer */
- sdbinvcnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
+ if (roce_get_field(sdb_issue_ptr,
+ ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_M,
+ ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S) ==
+ roce_get_field(sdb_send_ptr,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S)) {
+ old_send = roce_read(hr_dev, ROCEE_SDB_SEND_PTR_REG);
+ old_retry = roce_read(hr_dev, ROCEE_SDB_RETRY_CNT_REG);
- /* Query db's list status, until hw reversal */
do {
- sdbinvcnt_val = roce_read(hr_dev,
- ROCEE_SDB_INV_CNT_REG);
+ tsp_st = roce_read(hr_dev, ROCEE_TSP_BP_ST_REG);
+ if (roce_get_bit(tsp_st,
+ ROCEE_TSP_BP_ST_QH_FIFO_ENTRY_S) == 1) {
+ *wait_stage = HNS_ROCE_V1_DB_WAIT_OK;
+ return 0;
+ }
+
if (!time_before(jiffies, end)) {
- dev_err(dev, "destroy qp(0x%lx) timeout!!!",
- hr_qp->qpn);
- dev_err(dev, "SdbInvCnt = 0x%x\n",
- sdbinvcnt_val);
- break;
+ dev_dbg(dev, "QP(0x%lx) db process stage1 timeout when send ptr equals issue ptr.\n"
+ "issue 0x%x send 0x%x.\n",
+ hr_qp->qpn, sdb_issue_ptr,
+ sdb_send_ptr);
+ return 0;
+ }
+
+ msleep(HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS);
+
+ sdb_send_ptr = roce_read(hr_dev,
+ ROCEE_SDB_SEND_PTR_REG);
+ sdb_retry_cnt = roce_read(hr_dev,
+ ROCEE_SDB_RETRY_CNT_REG);
+ cur_cnt = roce_get_field(sdb_send_ptr,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
+ roce_get_field(sdb_retry_cnt,
+ ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M,
+ ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S);
+ if (!roce_get_bit(tsp_st,
+ ROCEE_CNT_CLR_CE_CNT_CLR_CE_S)) {
+ old_cnt = roce_get_field(old_send,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
+ roce_get_field(old_retry,
+ ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M,
+ ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S);
+ if (cur_cnt - old_cnt > SDB_ST_CMP_VAL)
+ success_flags = 1;
+ } else {
+ old_cnt = roce_get_field(old_send,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S);
+ if (cur_cnt - old_cnt > SDB_ST_CMP_VAL)
+ success_flags = 1;
+ else {
+ send_ptr = roce_get_field(old_send,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
+ roce_get_field(sdb_retry_cnt,
+ ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M,
+ ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S);
+ roce_set_field(old_send,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S,
+ send_ptr);
+ }
}
- } while ((short)(roce_get_field(sdbinvcnt_val,
- ROCEE_SDB_INV_CNT_SDB_INV_CNT_M,
- ROCEE_SDB_INV_CNT_SDB_INV_CNT_S) -
- (sdbinvcnt + SDB_INV_CNT_OFFSET)) < 0);
-
- /* Modify qp to reset before destroying qp */
- if (hns_roce_v1_qp_modify(hr_dev, NULL,
- to_hns_roce_state(
- (enum ib_qp_state)hr_qp->state),
- HNS_ROCE_QP_STATE_RST, NULL, hr_qp))
- dev_err(dev, "modify QP %06lx to RESET failed.\n",
- hr_qp->qpn);
+ } while (!success_flags);
}
+
+ *wait_stage = HNS_ROCE_V1_DB_STAGE2;
+
+ /* Get list pointer */
+ *sdb_inv_cnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
+ dev_dbg(dev, "QP(0x%lx) db process stage2. inv cnt = 0x%x.\n",
+ hr_qp->qpn, *sdb_inv_cnt);
+ }
+
+ if (*wait_stage == HNS_ROCE_V1_DB_STAGE2) {
+ /* Query db's list status, until hw reversal */
+ inv_cnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
+ while (roce_hw_index_cmp_lt(inv_cnt,
+ *sdb_inv_cnt + SDB_INV_CNT_OFFSET,
+ ROCEE_SDB_CNT_CMP_BITS)) {
+ if (!time_before(jiffies, end)) {
+ dev_dbg(dev, "QP(0x%lx) db process stage2 timeout. inv cnt 0x%x.\n",
+ hr_qp->qpn, inv_cnt);
+ return 0;
+ }
+
+ msleep(HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS);
+ inv_cnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
+ }
+
+ *wait_stage = HNS_ROCE_V1_DB_WAIT_OK;
+ }
+
+ return 0;
+}
+
+static int check_qp_reset_state(struct hns_roce_dev *hr_dev,
+ struct hns_roce_qp *hr_qp,
+ struct hns_roce_qp_work *qp_work_entry,
+ int *is_timeout)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 sdb_issue_ptr;
+ int ret;
+
+ if (hr_qp->state != IB_QPS_RESET) {
+ /* Set qp to ERR, waiting for hw complete processing all dbs */
+ ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
+ IB_QPS_ERR);
+ if (ret) {
+ dev_err(dev, "Modify QP(0x%lx) to ERR failed!\n",
+ hr_qp->qpn);
+ return ret;
+ }
+
+ /* Record issued doorbell */
+ sdb_issue_ptr = roce_read(hr_dev, ROCEE_SDB_ISSUE_PTR_REG);
+ qp_work_entry->sdb_issue_ptr = sdb_issue_ptr;
+ qp_work_entry->db_wait_stage = HNS_ROCE_V1_DB_STAGE1;
+
+ /* Query db process status, until hw process completely */
+ ret = check_qp_db_process_status(hr_dev, hr_qp, sdb_issue_ptr,
+ &qp_work_entry->sdb_inv_cnt,
+ &qp_work_entry->db_wait_stage);
+ if (ret) {
+ dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
+ hr_qp->qpn);
+ return ret;
+ }
+
+ if (qp_work_entry->db_wait_stage != HNS_ROCE_V1_DB_WAIT_OK) {
+ qp_work_entry->sche_cnt = 0;
+ *is_timeout = 1;
+ return 0;
+ }
+
+ /* Modify qp to reset before destroying qp */
+ ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
+ IB_QPS_RESET);
+ if (ret) {
+ dev_err(dev, "Modify QP(0x%lx) to RST failed!\n",
+ hr_qp->qpn);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
+{
+ struct hns_roce_qp_work *qp_work_entry;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_dev *hr_dev;
+ struct hns_roce_qp *hr_qp;
+ struct device *dev;
+ int ret;
+
+ qp_work_entry = container_of(work, struct hns_roce_qp_work, work);
+ hr_dev = to_hr_dev(qp_work_entry->ib_dev);
+ dev = &hr_dev->pdev->dev;
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ hr_qp = qp_work_entry->qp;
+
+ dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", hr_qp->qpn);
+
+ qp_work_entry->sche_cnt++;
+
+ /* Query db process status, until hw process completely */
+ ret = check_qp_db_process_status(hr_dev, hr_qp,
+ qp_work_entry->sdb_issue_ptr,
+ &qp_work_entry->sdb_inv_cnt,
+ &qp_work_entry->db_wait_stage);
+ if (ret) {
+ dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
+ hr_qp->qpn);
+ return;
+ }
+
+ if (qp_work_entry->db_wait_stage != HNS_ROCE_V1_DB_WAIT_OK &&
+ priv->des_qp.requeue_flag) {
+ queue_work(priv->des_qp.qp_wq, work);
+ return;
+ }
+
+ /* Modify qp to reset before destroying qp */
+ ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
+ IB_QPS_RESET);
+ if (ret) {
+ dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", hr_qp->qpn);
+ return;
+ }
+
+ hns_roce_qp_remove(hr_dev, hr_qp);
+ hns_roce_qp_free(hr_dev, hr_qp);
+
+ if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
+ /* RC QP, release QPN */
+ hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
+ kfree(hr_qp);
+ } else
+ kfree(hr_to_hr_sqp(hr_qp));
+
+ kfree(qp_work_entry);
+
+ dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", hr_qp->qpn);
+}
+
+int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_qp_work qp_work_entry;
+ struct hns_roce_qp_work *qp_work;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_cq *send_cq, *recv_cq;
+ int is_user = !!ibqp->pd->uobject;
+ int is_timeout = 0;
+ int ret;
+
+ ret = check_qp_reset_state(hr_dev, hr_qp, &qp_work_entry, &is_timeout);
+ if (ret) {
+ dev_err(dev, "QP reset state check failed(%d)!\n", ret);
+ return ret;
}
send_cq = to_hr_cq(hr_qp->ibqp.send_cq);
recv_cq = to_hr_cq(hr_qp->ibqp.recv_cq);
hns_roce_lock_cqs(send_cq, recv_cq);
-
if (!is_user) {
__hns_roce_v1_cq_clean(recv_cq, hr_qp->qpn, hr_qp->ibqp.srq ?
to_hr_srq(hr_qp->ibqp.srq) : NULL);
if (send_cq != recv_cq)
__hns_roce_v1_cq_clean(send_cq, hr_qp->qpn, NULL);
}
-
- hns_roce_qp_remove(hr_dev, hr_qp);
-
hns_roce_unlock_cqs(send_cq, recv_cq);
- hns_roce_qp_free(hr_dev, hr_qp);
+ if (!is_timeout) {
+ hns_roce_qp_remove(hr_dev, hr_qp);
+ hns_roce_qp_free(hr_dev, hr_qp);
- /* Not special_QP, free their QPN */
- if ((hr_qp->ibqp.qp_type == IB_QPT_RC) ||
- (hr_qp->ibqp.qp_type == IB_QPT_UC) ||
- (hr_qp->ibqp.qp_type == IB_QPT_UD))
- hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
+ /* RC QP, release QPN */
+ if (hr_qp->ibqp.qp_type == IB_QPT_RC)
+ hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
+ }
hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
- if (is_user) {
+ if (is_user)
ib_umem_release(hr_qp->umem);
- } else {
+ else {
kfree(hr_qp->sq.wrid);
kfree(hr_qp->rq.wrid);
+
hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf);
}
+
+ if (!is_timeout) {
+ if (hr_qp->ibqp.qp_type == IB_QPT_RC)
+ kfree(hr_qp);
+ else
+ kfree(hr_to_hr_sqp(hr_qp));
+ } else {
+ qp_work = kzalloc(sizeof(*qp_work), GFP_KERNEL);
+ if (!qp_work)
+ return -ENOMEM;
+
+ INIT_WORK(&qp_work->work, hns_roce_v1_destroy_qp_work_fn);
+ qp_work->ib_dev = &hr_dev->ib_dev;
+ qp_work->qp = hr_qp;
+ qp_work->db_wait_stage = qp_work_entry.db_wait_stage;
+ qp_work->sdb_issue_ptr = qp_work_entry.sdb_issue_ptr;
+ qp_work->sdb_inv_cnt = qp_work_entry.sdb_inv_cnt;
+ qp_work->sche_cnt = qp_work_entry.sche_cnt;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ queue_work(priv->des_qp.qp_wq, &qp_work->work);
+ dev_dbg(dev, "Begin destroy QP(0x%lx) work.\n", hr_qp->qpn);
+ }
+
+ return 0;
}
-int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
+int hns_roce_v1_destroy_cq(struct ib_cq *ibcq)
{
- struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
- struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibcq->device);
+ struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 cqe_cnt_ori;
+ u32 cqe_cnt_cur;
+ u32 cq_buf_size;
+ int wait_time = 0;
+ int ret = 0;
- hns_roce_v1_destroy_qp_common(hr_dev, hr_qp, !!ibqp->pd->uobject);
+ hns_roce_free_cq(hr_dev, hr_cq);
- if (hr_qp->ibqp.qp_type == IB_QPT_GSI)
- kfree(hr_to_hr_sqp(hr_qp));
- else
- kfree(hr_qp);
+ /*
+ * Before freeing cq buffer, we need to ensure that the outstanding CQE
+ * have been written by checking the CQE counter.
+ */
+ cqe_cnt_ori = roce_read(hr_dev, ROCEE_SCAEP_WR_CQE_CNT);
+ while (1) {
+ if (roce_read(hr_dev, ROCEE_CAEP_CQE_WCMD_EMPTY) &
+ HNS_ROCE_CQE_WCMD_EMPTY_BIT)
+ break;
- return 0;
+ cqe_cnt_cur = roce_read(hr_dev, ROCEE_SCAEP_WR_CQE_CNT);
+ if ((cqe_cnt_cur - cqe_cnt_ori) >= HNS_ROCE_MIN_CQE_CNT)
+ break;
+
+ msleep(HNS_ROCE_EACH_FREE_CQ_WAIT_MSECS);
+ if (wait_time > HNS_ROCE_MAX_FREE_CQ_WAIT_CNT) {
+ dev_warn(dev, "Destroy cq 0x%lx timeout!\n",
+ hr_cq->cqn);
+ ret = -ETIMEDOUT;
+ break;
+ }
+ wait_time++;
+ }
+
+ hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
+
+ if (ibcq->uobject)
+ ib_umem_release(hr_cq->umem);
+ else {
+ /* Free the buff of stored cq */
+ cq_buf_size = (ibcq->cqe + 1) * hr_dev->caps.cq_entry_sz;
+ hns_roce_buf_free(hr_dev, cq_buf_size, &hr_cq->hr_buf.hr_buf);
+ }
+
+ kfree(hr_cq);
+
+ return ret;
}
struct hns_roce_v1_priv hr_v1_priv;
@@ -2917,5 +3835,7 @@ struct hns_roce_hw hns_roce_hw_v1 = {
.post_recv = hns_roce_v1_post_recv,
.req_notify_cq = hns_roce_v1_req_notify_cq,
.poll_cq = hns_roce_v1_poll_cq,
+ .dereg_mr = hns_roce_v1_dereg_mr,
+ .destroy_cq = hns_roce_v1_destroy_cq,
.priv = &hr_v1_priv,
};
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
index 539b0a3b92b0..b213b5e6fef1 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
@@ -58,6 +58,7 @@
#define HNS_ROCE_V1_PHY_UAR_NUM 8
#define HNS_ROCE_V1_GID_NUM 16
+#define HNS_ROCE_V1_RESV_QP 8
#define HNS_ROCE_V1_NUM_COMP_EQE 0x8000
#define HNS_ROCE_V1_NUM_ASYNC_EQE 0x400
@@ -102,8 +103,22 @@
#define HNS_ROCE_V1_EXT_ODB_ALFUL \
(HNS_ROCE_V1_EXT_ODB_DEPTH - HNS_ROCE_V1_DB_RSVD)
+#define HNS_ROCE_V1_DB_WAIT_OK 0
+#define HNS_ROCE_V1_DB_STAGE1 1
+#define HNS_ROCE_V1_DB_STAGE2 2
+#define HNS_ROCE_V1_CHECK_DB_TIMEOUT_MSECS 10000
+#define HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS 20
+#define HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS 50000
+#define HNS_ROCE_V1_RECREATE_LP_QP_TIMEOUT_MSECS 10000
+#define HNS_ROCE_V1_FREE_MR_WAIT_VALUE 5
+#define HNS_ROCE_V1_RECREATE_LP_QP_WAIT_VALUE 20
+
#define HNS_ROCE_BT_RSV_BUF_SIZE (1 << 17)
+#define HNS_ROCE_V1_TPTR_ENTRY_SIZE 2
+#define HNS_ROCE_V1_TPTR_BUF_SIZE \
+ (HNS_ROCE_V1_TPTR_ENTRY_SIZE * HNS_ROCE_V1_MAX_CQ_NUM)
+
#define HNS_ROCE_ODB_POLL_MODE 0
#define HNS_ROCE_SDB_NORMAL_MODE 0
@@ -140,6 +155,7 @@
#define SQ_PSN_SHIFT 8
#define QKEY_VAL 0x80010000
#define SDB_INV_CNT_OFFSET 8
+#define SDB_ST_CMP_VAL 8
struct hns_roce_cq_context {
u32 cqc_byte_4;
@@ -436,6 +452,8 @@ struct hns_roce_ud_send_wqe {
#define UD_SEND_WQE_U32_8_DMAC_5_M \
(((1UL << 8) - 1) << UD_SEND_WQE_U32_8_DMAC_5_S)
+#define UD_SEND_WQE_U32_8_LOOPBACK_INDICATOR_S 22
+
#define UD_SEND_WQE_U32_8_OPERATION_TYPE_S 16
#define UD_SEND_WQE_U32_8_OPERATION_TYPE_M \
(((1UL << 4) - 1) << UD_SEND_WQE_U32_8_OPERATION_TYPE_S)
@@ -480,13 +498,17 @@ struct hns_roce_sqp_context {
u32 qp1c_bytes_12;
u32 qp1c_bytes_16;
u32 qp1c_bytes_20;
- u32 qp1c_bytes_28;
u32 cur_rq_wqe_ba_l;
+ u32 qp1c_bytes_28;
u32 qp1c_bytes_32;
u32 cur_sq_wqe_ba_l;
u32 qp1c_bytes_40;
};
+#define QP1C_BYTES_4_QP_STATE_S 0
+#define QP1C_BYTES_4_QP_STATE_M \
+ (((1UL << 3) - 1) << QP1C_BYTES_4_QP_STATE_S)
+
#define QP1C_BYTES_4_SQ_WQE_SHIFT_S 8
#define QP1C_BYTES_4_SQ_WQE_SHIFT_M \
(((1UL << 4) - 1) << QP1C_BYTES_4_SQ_WQE_SHIFT_S)
@@ -952,6 +974,10 @@ struct hns_roce_sq_db {
#define SQ_DOORBELL_U32_4_SQ_HEAD_M \
(((1UL << 15) - 1) << SQ_DOORBELL_U32_4_SQ_HEAD_S)
+#define SQ_DOORBELL_U32_4_SL_S 16
+#define SQ_DOORBELL_U32_4_SL_M \
+ (((1UL << 2) - 1) << SQ_DOORBELL_U32_4_SL_S)
+
#define SQ_DOORBELL_U32_4_PORT_S 18
#define SQ_DOORBELL_U32_4_PORT_M (((1UL << 3) - 1) << SQ_DOORBELL_U32_4_PORT_S)
@@ -979,12 +1005,58 @@ struct hns_roce_bt_table {
struct hns_roce_buf_list cqc_buf;
};
+struct hns_roce_tptr_table {
+ struct hns_roce_buf_list tptr_buf;
+};
+
+struct hns_roce_qp_work {
+ struct work_struct work;
+ struct ib_device *ib_dev;
+ struct hns_roce_qp *qp;
+ u32 db_wait_stage;
+ u32 sdb_issue_ptr;
+ u32 sdb_inv_cnt;
+ u32 sche_cnt;
+};
+
+struct hns_roce_des_qp {
+ struct workqueue_struct *qp_wq;
+ int requeue_flag;
+};
+
+struct hns_roce_mr_free_work {
+ struct work_struct work;
+ struct ib_device *ib_dev;
+ struct completion *comp;
+ int comp_flag;
+ void *mr;
+};
+
+struct hns_roce_recreate_lp_qp_work {
+ struct work_struct work;
+ struct ib_device *ib_dev;
+ struct completion *comp;
+ int comp_flag;
+};
+
+struct hns_roce_free_mr {
+ struct workqueue_struct *free_mr_wq;
+ struct hns_roce_qp *mr_free_qp[HNS_ROCE_V1_RESV_QP];
+ struct hns_roce_cq *mr_free_cq;
+ struct hns_roce_pd *mr_free_pd;
+};
+
struct hns_roce_v1_priv {
struct hns_roce_db_table db_table;
struct hns_roce_raq_table raq_table;
struct hns_roce_bt_table bt_table;
+ struct hns_roce_tptr_table tptr_table;
+ struct hns_roce_des_qp des_qp;
+ struct hns_roce_free_mr free_mr;
};
int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset);
+int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+int hns_roce_v1_destroy_qp(struct ib_qp *ibqp);
#endif
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index 764e35a54457..4953d9cb83a7 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -35,52 +35,13 @@
#include <rdma/ib_addr.h>
#include <rdma/ib_smi.h>
#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_cache.h>
#include "hns_roce_common.h"
#include "hns_roce_device.h"
-#include "hns_roce_user.h"
+#include <rdma/hns-abi.h>
#include "hns_roce_hem.h"
/**
- * hns_roce_addrconf_ifid_eui48 - Get default gid.
- * @eui: eui.
- * @vlan_id: gid
- * @dev: net device
- * Description:
- * MAC convert to GID
- * gid[0..7] = fe80 0000 0000 0000
- * gid[8] = mac[0] ^ 2
- * gid[9] = mac[1]
- * gid[10] = mac[2]
- * gid[11] = ff (VLAN ID high byte (4 MS bits))
- * gid[12] = fe (VLAN ID low byte)
- * gid[13] = mac[3]
- * gid[14] = mac[4]
- * gid[15] = mac[5]
- */
-static void hns_roce_addrconf_ifid_eui48(u8 *eui, u16 vlan_id,
- struct net_device *dev)
-{
- memcpy(eui, dev->dev_addr, 3);
- memcpy(eui + 5, dev->dev_addr + 3, 3);
- if (vlan_id < 0x1000) {
- eui[3] = vlan_id >> 8;
- eui[4] = vlan_id & 0xff;
- } else {
- eui[3] = 0xff;
- eui[4] = 0xfe;
- }
- eui[0] ^= 2;
-}
-
-static void hns_roce_make_default_gid(struct net_device *dev, union ib_gid *gid)
-{
- memset(gid, 0, sizeof(*gid));
- gid->raw[0] = 0xFE;
- gid->raw[1] = 0x80;
- hns_roce_addrconf_ifid_eui48(&gid->raw[8], 0xffff, dev);
-}
-
-/**
* hns_get_gid_index - Get gid index.
* @hr_dev: pointer to structure hns_roce_dev.
* @port: port, value range: 0 ~ MAX
@@ -96,30 +57,6 @@ int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, int gid_index)
return gid_index * hr_dev->caps.num_ports + port;
}
-static int hns_roce_set_gid(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
- union ib_gid *gid)
-{
- struct device *dev = &hr_dev->pdev->dev;
- u8 gid_idx = 0;
-
- if (gid_index >= hr_dev->caps.gid_table_len[port]) {
- dev_err(dev, "gid_index %d illegal, port %d gid range: 0~%d\n",
- gid_index, port, hr_dev->caps.gid_table_len[port] - 1);
- return -EINVAL;
- }
-
- gid_idx = hns_get_gid_index(hr_dev, port, gid_index);
-
- if (!memcmp(gid, &hr_dev->iboe.gid_table[gid_idx], sizeof(*gid)))
- return -EINVAL;
-
- memcpy(&hr_dev->iboe.gid_table[gid_idx], gid, sizeof(*gid));
-
- hr_dev->hw->set_gid(hr_dev, port, gid_index, gid);
-
- return 0;
-}
-
static void hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 port, u8 *addr)
{
u8 phy_port;
@@ -135,27 +72,44 @@ static void hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 port, u8 *addr)
hr_dev->hw->set_mac(hr_dev, phy_port, addr);
}
-static void hns_roce_set_mtu(struct hns_roce_dev *hr_dev, u8 port, int mtu)
+static int hns_roce_add_gid(struct ib_device *device, u8 port_num,
+ unsigned int index, const union ib_gid *gid,
+ const struct ib_gid_attr *attr, void **context)
{
- u8 phy_port = hr_dev->iboe.phy_port[port];
- enum ib_mtu tmp;
+ struct hns_roce_dev *hr_dev = to_hr_dev(device);
+ u8 port = port_num - 1;
+ unsigned long flags;
+
+ if (port >= hr_dev->caps.num_ports)
+ return -EINVAL;
+
+ spin_lock_irqsave(&hr_dev->iboe.lock, flags);
- tmp = iboe_get_mtu(mtu);
- if (!tmp)
- tmp = IB_MTU_256;
+ hr_dev->hw->set_gid(hr_dev, port, index, (union ib_gid *)gid);
- hr_dev->hw->set_mtu(hr_dev, phy_port, tmp);
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+
+ return 0;
}
-static void hns_roce_update_gids(struct hns_roce_dev *hr_dev, int port)
+static int hns_roce_del_gid(struct ib_device *device, u8 port_num,
+ unsigned int index, void **context)
{
- struct ib_event event;
+ struct hns_roce_dev *hr_dev = to_hr_dev(device);
+ union ib_gid zgid = { {0} };
+ u8 port = port_num - 1;
+ unsigned long flags;
+
+ if (port >= hr_dev->caps.num_ports)
+ return -EINVAL;
+
+ spin_lock_irqsave(&hr_dev->iboe.lock, flags);
- /* Refresh gid in ib_cache */
- event.device = &hr_dev->ib_dev;
- event.element.port_num = port + 1;
- event.event = IB_EVENT_GID_CHANGE;
- ib_dispatch_event(&event);
+ hr_dev->hw->set_gid(hr_dev, port, index, &zgid);
+
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+
+ return 0;
}
static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
@@ -163,9 +117,6 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
{
struct device *dev = &hr_dev->pdev->dev;
struct net_device *netdev;
- unsigned long flags;
- union ib_gid gid;
- int ret = 0;
netdev = hr_dev->iboe.netdevs[port];
if (!netdev) {
@@ -173,7 +124,7 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
return -ENODEV;
}
- spin_lock_irqsave(&hr_dev->iboe.lock, flags);
+ spin_lock_bh(&hr_dev->iboe.lock);
switch (event) {
case NETDEV_UP:
@@ -181,23 +132,19 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
case NETDEV_REGISTER:
case NETDEV_CHANGEADDR:
hns_roce_set_mac(hr_dev, port, netdev->dev_addr);
- hns_roce_make_default_gid(netdev, &gid);
- ret = hns_roce_set_gid(hr_dev, port, 0, &gid);
- if (!ret)
- hns_roce_update_gids(hr_dev, port);
break;
case NETDEV_DOWN:
/*
- * In v1 engine, only support all ports closed together.
- */
+ * In v1 engine, only support all ports closed together.
+ */
break;
default:
dev_dbg(dev, "NETDEV event = 0x%x!\n", (u32)(event));
break;
}
- spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
- return ret;
+ spin_unlock_bh(&hr_dev->iboe.lock);
+ return 0;
}
static int hns_roce_netdev_event(struct notifier_block *self,
@@ -224,118 +171,17 @@ static int hns_roce_netdev_event(struct notifier_block *self,
return NOTIFY_DONE;
}
-static void hns_roce_addr_event(int event, struct net_device *event_netdev,
- struct hns_roce_dev *hr_dev, union ib_gid *gid)
+static int hns_roce_setup_mtu_mac(struct hns_roce_dev *hr_dev)
{
- struct hns_roce_ib_iboe *iboe = NULL;
- int gid_table_len = 0;
- unsigned long flags;
- union ib_gid zgid;
- u8 gid_idx = 0;
- u8 port = 0;
- int i = 0;
- int free;
- struct net_device *real_dev = rdma_vlan_dev_real_dev(event_netdev) ?
- rdma_vlan_dev_real_dev(event_netdev) :
- event_netdev;
-
- if (event != NETDEV_UP && event != NETDEV_DOWN)
- return;
-
- iboe = &hr_dev->iboe;
- while (port < hr_dev->caps.num_ports) {
- if (real_dev == iboe->netdevs[port])
- break;
- port++;
- }
-
- if (port >= hr_dev->caps.num_ports) {
- dev_dbg(&hr_dev->pdev->dev, "can't find netdev\n");
- return;
- }
-
- memset(zgid.raw, 0, sizeof(zgid.raw));
- free = -1;
- gid_table_len = hr_dev->caps.gid_table_len[port];
-
- spin_lock_irqsave(&hr_dev->iboe.lock, flags);
-
- for (i = 0; i < gid_table_len; i++) {
- gid_idx = hns_get_gid_index(hr_dev, port, i);
- if (!memcmp(gid->raw, iboe->gid_table[gid_idx].raw,
- sizeof(gid->raw)))
- break;
- if (free < 0 && !memcmp(zgid.raw,
- iboe->gid_table[gid_idx].raw, sizeof(zgid.raw)))
- free = i;
- }
-
- if (i >= gid_table_len) {
- if (free < 0) {
- spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
- dev_dbg(&hr_dev->pdev->dev,
- "gid_index overflow, port(%d)\n", port);
- return;
- }
- if (!hns_roce_set_gid(hr_dev, port, free, gid))
- hns_roce_update_gids(hr_dev, port);
- } else if (event == NETDEV_DOWN) {
- if (!hns_roce_set_gid(hr_dev, port, i, &zgid))
- hns_roce_update_gids(hr_dev, port);
- }
-
- spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
-}
-
-static int hns_roce_inet_event(struct notifier_block *self, unsigned long event,
- void *ptr)
-{
- struct in_ifaddr *ifa = ptr;
- struct hns_roce_dev *hr_dev;
- struct net_device *dev = ifa->ifa_dev->dev;
- union ib_gid gid;
-
- ipv6_addr_set_v4mapped(ifa->ifa_address, (struct in6_addr *)&gid);
-
- hr_dev = container_of(self, struct hns_roce_dev, iboe.nb_inet);
-
- hns_roce_addr_event(event, dev, hr_dev, &gid);
-
- return NOTIFY_DONE;
-}
-
-static int hns_roce_setup_mtu_gids(struct hns_roce_dev *hr_dev)
-{
- struct in_ifaddr *ifa_list = NULL;
- union ib_gid gid = {{0} };
- u32 ipaddr = 0;
- int index = 0;
- int ret = 0;
- u8 i = 0;
+ u8 i;
for (i = 0; i < hr_dev->caps.num_ports; i++) {
- hns_roce_set_mtu(hr_dev, i,
- ib_mtu_enum_to_int(hr_dev->caps.max_mtu));
+ hr_dev->hw->set_mtu(hr_dev, hr_dev->iboe.phy_port[i],
+ hr_dev->caps.max_mtu);
hns_roce_set_mac(hr_dev, i, hr_dev->iboe.netdevs[i]->dev_addr);
-
- if (hr_dev->iboe.netdevs[i]->ip_ptr) {
- ifa_list = hr_dev->iboe.netdevs[i]->ip_ptr->ifa_list;
- index = 1;
- while (ifa_list) {
- ipaddr = ifa_list->ifa_address;
- ipv6_addr_set_v4mapped(ipaddr,
- (struct in6_addr *)&gid);
- ret = hns_roce_set_gid(hr_dev, i, index, &gid);
- if (ret)
- break;
- index++;
- ifa_list = ifa_list->ifa_next;
- }
- hns_roce_update_gids(hr_dev, i);
- }
}
- return ret;
+ return 0;
}
static int hns_roce_query_device(struct ib_device *ib_dev,
@@ -444,31 +290,6 @@ static enum rdma_link_layer hns_roce_get_link_layer(struct ib_device *device,
static int hns_roce_query_gid(struct ib_device *ib_dev, u8 port_num, int index,
union ib_gid *gid)
{
- struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
- struct device *dev = &hr_dev->pdev->dev;
- u8 gid_idx = 0;
- u8 port;
-
- if (port_num < 1 || port_num > hr_dev->caps.num_ports ||
- index >= hr_dev->caps.gid_table_len[port_num - 1]) {
- dev_err(dev,
- "port_num %d index %d illegal! correct range: port_num 1~%d index 0~%d!\n",
- port_num, index, hr_dev->caps.num_ports,
- hr_dev->caps.gid_table_len[port_num - 1] - 1);
- return -EINVAL;
- }
-
- port = port_num - 1;
- gid_idx = hns_get_gid_index(hr_dev, port, index);
- if (gid_idx >= HNS_ROCE_MAX_GID_NUM) {
- dev_err(dev, "port_num %d index %d illegal! total gid num %d!\n",
- port_num, index, HNS_ROCE_MAX_GID_NUM);
- return -EINVAL;
- }
-
- memcpy(gid->raw, hr_dev->iboe.gid_table[gid_idx].raw,
- HNS_ROCE_GID_SIZE);
-
return 0;
}
@@ -549,6 +370,8 @@ static int hns_roce_dealloc_ucontext(struct ib_ucontext *ibcontext)
static int hns_roce_mmap(struct ib_ucontext *context,
struct vm_area_struct *vma)
{
+ struct hns_roce_dev *hr_dev = to_hr_dev(context->device);
+
if (((vma->vm_end - vma->vm_start) % PAGE_SIZE) != 0)
return -EINVAL;
@@ -558,10 +381,15 @@ static int hns_roce_mmap(struct ib_ucontext *context,
to_hr_ucontext(context)->uar.pfn,
PAGE_SIZE, vma->vm_page_prot))
return -EAGAIN;
-
- } else {
+ } else if (vma->vm_pgoff == 1 && hr_dev->hw_rev == HNS_ROCE_HW_VER1) {
+ /* vm_pgoff: 1 -- TPTR */
+ if (io_remap_pfn_range(vma, vma->vm_start,
+ hr_dev->tptr_dma_addr >> PAGE_SHIFT,
+ hr_dev->tptr_size,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ } else
return -EINVAL;
- }
return 0;
}
@@ -605,7 +433,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
spin_lock_init(&iboe->lock);
ib_dev = &hr_dev->ib_dev;
- strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX);
+ strlcpy(ib_dev->name, "hns_%d", IB_DEVICE_NAME_MAX);
ib_dev->owner = THIS_MODULE;
ib_dev->node_type = RDMA_NODE_IB_CA;
@@ -639,6 +467,8 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
ib_dev->get_link_layer = hns_roce_get_link_layer;
ib_dev->get_netdev = hns_roce_get_netdev;
ib_dev->query_gid = hns_roce_query_gid;
+ ib_dev->add_gid = hns_roce_add_gid;
+ ib_dev->del_gid = hns_roce_del_gid;
ib_dev->query_pkey = hns_roce_query_pkey;
ib_dev->alloc_ucontext = hns_roce_alloc_ucontext;
ib_dev->dealloc_ucontext = hns_roce_dealloc_ucontext;
@@ -681,32 +511,22 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
return ret;
}
- ret = hns_roce_setup_mtu_gids(hr_dev);
+ ret = hns_roce_setup_mtu_mac(hr_dev);
if (ret) {
- dev_err(dev, "roce_setup_mtu_gids failed!\n");
- goto error_failed_setup_mtu_gids;
+ dev_err(dev, "setup_mtu_mac failed!\n");
+ goto error_failed_setup_mtu_mac;
}
iboe->nb.notifier_call = hns_roce_netdev_event;
ret = register_netdevice_notifier(&iboe->nb);
if (ret) {
dev_err(dev, "register_netdevice_notifier failed!\n");
- goto error_failed_setup_mtu_gids;
- }
-
- iboe->nb_inet.notifier_call = hns_roce_inet_event;
- ret = register_inetaddr_notifier(&iboe->nb_inet);
- if (ret) {
- dev_err(dev, "register inet addr notifier failed!\n");
- goto error_failed_register_inetaddr_notifier;
+ goto error_failed_setup_mtu_mac;
}
return 0;
-error_failed_register_inetaddr_notifier:
- unregister_netdevice_notifier(&iboe->nb);
-
-error_failed_setup_mtu_gids:
+error_failed_setup_mtu_mac:
ib_unregister_device(ib_dev);
return ret;
@@ -940,10 +760,10 @@ err_unmap_mtt:
}
/**
-* hns_roce_setup_hca - setup host channel adapter
-* @hr_dev: pointer to hns roce device
-* Return : int
-*/
+ * hns_roce_setup_hca - setup host channel adapter
+ * @hr_dev: pointer to hns roce device
+ * Return : int
+ */
static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
{
int ret;
@@ -1008,11 +828,11 @@ err_uar_table_free:
}
/**
-* hns_roce_probe - RoCE driver entrance
-* @pdev: pointer to platform device
-* Return : int
-*
-*/
+ * hns_roce_probe - RoCE driver entrance
+ * @pdev: pointer to platform device
+ * Return : int
+ *
+ */
static int hns_roce_probe(struct platform_device *pdev)
{
int ret;
@@ -1023,9 +843,6 @@ static int hns_roce_probe(struct platform_device *pdev)
if (!hr_dev)
return -ENOMEM;
- memset((u8 *)hr_dev + sizeof(struct ib_device), 0,
- sizeof(struct hns_roce_dev) - sizeof(struct ib_device));
-
hr_dev->pdev = pdev;
platform_set_drvdata(pdev, hr_dev);
@@ -1125,9 +942,9 @@ error_failed_get_cfg:
}
/**
-* hns_roce_remove - remove RoCE device
-* @pdev: pointer to platform device
-*/
+ * hns_roce_remove - remove RoCE device
+ * @pdev: pointer to platform device
+ */
static int hns_roce_remove(struct platform_device *pdev)
{
struct hns_roce_dev *hr_dev = platform_get_drvdata(pdev);
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
index fb87883ead34..4139abee3b54 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -42,7 +42,7 @@ static u32 hw_index_to_key(unsigned long ind)
return (u32)(ind >> 24) | (ind << 8);
}
-static unsigned long key_to_hw_index(u32 key)
+unsigned long key_to_hw_index(u32 key)
{
return (key << 24) | (key >> 8);
}
@@ -53,16 +53,16 @@ static int hns_roce_sw2hw_mpt(struct hns_roce_dev *hr_dev,
{
return hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, mpt_index, 0,
HNS_ROCE_CMD_SW2HW_MPT,
- HNS_ROCE_CMD_TIME_CLASS_B);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
}
-static int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
+int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
struct hns_roce_cmd_mailbox *mailbox,
unsigned long mpt_index)
{
return hns_roce_cmd_mbox(hr_dev, 0, mailbox ? mailbox->dma : 0,
mpt_index, !mailbox, HNS_ROCE_CMD_HW2SW_MPT,
- HNS_ROCE_CMD_TIME_CLASS_B);
+ HNS_ROCE_CMD_TIMEOUT_MSECS);
}
static int hns_roce_buddy_alloc(struct hns_roce_buddy *buddy, int order,
@@ -137,11 +137,13 @@ static int hns_roce_buddy_init(struct hns_roce_buddy *buddy, int max_order)
for (i = 0; i <= buddy->max_order; ++i) {
s = BITS_TO_LONGS(1 << (buddy->max_order - i));
- buddy->bits[i] = kmalloc_array(s, sizeof(long), GFP_KERNEL);
- if (!buddy->bits[i])
- goto err_out_free;
-
- bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i));
+ buddy->bits[i] = kcalloc(s, sizeof(long), GFP_KERNEL |
+ __GFP_NOWARN);
+ if (!buddy->bits[i]) {
+ buddy->bits[i] = vzalloc(s * sizeof(long));
+ if (!buddy->bits[i])
+ goto err_out_free;
+ }
}
set_bit(0, buddy->bits[buddy->max_order]);
@@ -151,7 +153,7 @@ static int hns_roce_buddy_init(struct hns_roce_buddy *buddy, int max_order)
err_out_free:
for (i = 0; i <= buddy->max_order; ++i)
- kfree(buddy->bits[i]);
+ kvfree(buddy->bits[i]);
err_out:
kfree(buddy->bits);
@@ -164,7 +166,7 @@ static void hns_roce_buddy_cleanup(struct hns_roce_buddy *buddy)
int i;
for (i = 0; i <= buddy->max_order; ++i)
- kfree(buddy->bits[i]);
+ kvfree(buddy->bits[i]);
kfree(buddy->bits);
kfree(buddy->num_free);
@@ -287,7 +289,7 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev,
}
hns_roce_bitmap_free(&hr_dev->mr_table.mtpt_bitmap,
- key_to_hw_index(mr->key));
+ key_to_hw_index(mr->key), BITMAP_NO_RR);
}
static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev,
@@ -605,13 +607,20 @@ err_free:
int hns_roce_dereg_mr(struct ib_mr *ibmr)
{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
struct hns_roce_mr *mr = to_hr_mr(ibmr);
+ int ret = 0;
- hns_roce_mr_free(to_hr_dev(ibmr->device), mr);
- if (mr->umem)
- ib_umem_release(mr->umem);
+ if (hr_dev->hw->dereg_mr) {
+ ret = hr_dev->hw->dereg_mr(hr_dev, mr);
+ } else {
+ hns_roce_mr_free(hr_dev, mr);
- kfree(mr);
+ if (mr->umem)
+ ib_umem_release(mr->umem);
- return 0;
+ kfree(mr);
+ }
+
+ return ret;
}
diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c
index 05db7d59812a..a64500fa1145 100644
--- a/drivers/infiniband/hw/hns/hns_roce_pd.c
+++ b/drivers/infiniband/hw/hns/hns_roce_pd.c
@@ -40,7 +40,7 @@ static int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, unsigned long *pdn)
static void hns_roce_pd_free(struct hns_roce_dev *hr_dev, unsigned long pdn)
{
- hns_roce_bitmap_free(&hr_dev->pd_bitmap, pdn);
+ hns_roce_bitmap_free(&hr_dev->pd_bitmap, pdn, BITMAP_NO_RR);
}
int hns_roce_init_pd_table(struct hns_roce_dev *hr_dev)
@@ -121,7 +121,8 @@ int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
void hns_roce_uar_free(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
{
- hns_roce_bitmap_free(&hr_dev->uar_table.bitmap, uar->index);
+ hns_roce_bitmap_free(&hr_dev->uar_table.bitmap, uar->index,
+ BITMAP_NO_RR);
}
int hns_roce_init_uar_table(struct hns_roce_dev *hr_dev)
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index e86dd8d06777..f036f32f15d3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -37,7 +37,7 @@
#include "hns_roce_common.h"
#include "hns_roce_device.h"
#include "hns_roce_hem.h"
-#include "hns_roce_user.h"
+#include <rdma/hns-abi.h>
#define SQP_NUM (2 * HNS_ROCE_MAX_PORTS)
@@ -250,7 +250,7 @@ void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn,
if (base_qpn < SQP_NUM)
return;
- hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt);
+ hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt, BITMAP_RR);
}
static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev,
diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h
index 8ec09e470f84..da2eb5a281fa 100644
--- a/drivers/infiniband/hw/i40iw/i40iw.h
+++ b/drivers/infiniband/hw/i40iw/i40iw.h
@@ -112,9 +112,12 @@
#define I40IW_DRV_OPT_MCAST_LOGPORT_MAP 0x00000800
#define IW_HMC_OBJ_TYPE_NUM ARRAY_SIZE(iw_hmc_obj_types)
-#define IW_CFG_FPM_QP_COUNT 32768
-#define I40IW_MAX_PAGES_PER_FMR 512
-#define I40IW_MIN_PAGES_PER_FMR 1
+#define IW_CFG_FPM_QP_COUNT 32768
+#define I40IW_MAX_PAGES_PER_FMR 512
+#define I40IW_MIN_PAGES_PER_FMR 1
+#define I40IW_CQP_COMPL_RQ_WQE_FLUSHED 2
+#define I40IW_CQP_COMPL_SQ_WQE_FLUSHED 3
+#define I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED 4
#define I40IW_MTU_TO_MSS 40
#define I40IW_DEFAULT_MSS 1460
@@ -210,6 +213,12 @@ struct i40iw_msix_vector {
u32 ceq_id;
};
+struct l2params_work {
+ struct work_struct work;
+ struct i40iw_device *iwdev;
+ struct i40iw_l2params l2params;
+};
+
#define I40IW_MSIX_TABLE_SIZE 65
struct virtchnl_work {
@@ -227,6 +236,7 @@ struct i40iw_device {
struct net_device *netdev;
wait_queue_head_t vchnl_waitq;
struct i40iw_sc_dev sc_dev;
+ struct i40iw_sc_vsi vsi;
struct i40iw_handler *hdl;
struct i40e_info *ldev;
struct i40e_client *client;
@@ -280,7 +290,6 @@ struct i40iw_device {
u32 sd_type;
struct workqueue_struct *param_wq;
atomic_t params_busy;
- u32 mss;
enum init_completion_state init_state;
u16 mac_ip_table_idx;
atomic_t vchnl_msgs;
@@ -297,6 +306,14 @@ struct i40iw_device {
u32 mr_stagmask;
u32 mpa_version;
bool dcb;
+ bool closing;
+ bool reset;
+ u32 used_pds;
+ u32 used_cqs;
+ u32 used_mrs;
+ u32 used_qps;
+ wait_queue_head_t close_wq;
+ atomic64_t use_count;
};
struct i40iw_ib_device {
@@ -498,7 +515,7 @@ u32 i40iw_initialize_hw_resources(struct i40iw_device *iwdev);
int i40iw_register_rdma_device(struct i40iw_device *iwdev);
void i40iw_port_ibevent(struct i40iw_device *iwdev);
-int i40iw_cm_disconn(struct i40iw_qp *);
+void i40iw_cm_disconn(struct i40iw_qp *iwqp);
void i40iw_cm_disconn_worker(void *);
int mini_cm_recv_pkt(struct i40iw_cm_core *, struct i40iw_device *,
struct sk_buff *);
@@ -508,20 +525,26 @@ enum i40iw_status_code i40iw_handle_cqp_op(struct i40iw_device *iwdev,
enum i40iw_status_code i40iw_add_mac_addr(struct i40iw_device *iwdev,
u8 *mac_addr, u8 *mac_index);
int i40iw_modify_qp(struct ib_qp *, struct ib_qp_attr *, int, struct ib_udata *);
+void i40iw_cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq);
void i40iw_rem_pdusecount(struct i40iw_pd *iwpd, struct i40iw_device *iwdev);
void i40iw_add_pdusecount(struct i40iw_pd *iwpd);
+void i40iw_rem_devusecount(struct i40iw_device *iwdev);
+void i40iw_add_devusecount(struct i40iw_device *iwdev);
void i40iw_hw_modify_qp(struct i40iw_device *iwdev, struct i40iw_qp *iwqp,
struct i40iw_modify_qp_info *info, bool wait);
+void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev,
+ struct i40iw_sc_qp *qp,
+ bool suspend);
enum i40iw_status_code i40iw_manage_qhash(struct i40iw_device *iwdev,
struct i40iw_cm_info *cminfo,
enum i40iw_quad_entry_type etype,
enum i40iw_quad_hash_manage_type mtype,
void *cmnode,
bool wait);
-void i40iw_receive_ilq(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *rbuf);
-void i40iw_free_sqbuf(struct i40iw_sc_dev *dev, void *bufp);
+void i40iw_receive_ilq(struct i40iw_sc_vsi *vsi, struct i40iw_puda_buf *rbuf);
+void i40iw_free_sqbuf(struct i40iw_sc_vsi *vsi, void *bufp);
void i40iw_free_qp_resources(struct i40iw_device *iwdev,
struct i40iw_qp *iwqp,
u32 qp_num);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c
index 85637696f6e9..95a0586a4da8 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c
@@ -68,13 +68,13 @@ static void i40iw_disconnect_worker(struct work_struct *work);
/**
* i40iw_free_sqbuf - put back puda buffer if refcount = 0
- * @dev: FPK device
+ * @vsi: pointer to vsi structure
* @buf: puda buffer to free
*/
-void i40iw_free_sqbuf(struct i40iw_sc_dev *dev, void *bufp)
+void i40iw_free_sqbuf(struct i40iw_sc_vsi *vsi, void *bufp)
{
struct i40iw_puda_buf *buf = (struct i40iw_puda_buf *)bufp;
- struct i40iw_puda_rsrc *ilq = dev->ilq;
+ struct i40iw_puda_rsrc *ilq = vsi->ilq;
if (!atomic_dec_return(&buf->refcount))
i40iw_puda_ret_bufpool(ilq, buf);
@@ -221,6 +221,7 @@ static void i40iw_get_addr_info(struct i40iw_cm_node *cm_node,
memcpy(cm_info->rem_addr, cm_node->rem_addr, sizeof(cm_info->rem_addr));
cm_info->loc_port = cm_node->loc_port;
cm_info->rem_port = cm_node->rem_port;
+ cm_info->user_pri = cm_node->user_pri;
}
/**
@@ -271,6 +272,7 @@ static int i40iw_send_cm_event(struct i40iw_cm_node *cm_node,
event.provider_data = (void *)cm_node;
event.private_data = (void *)cm_node->pdata_buf;
event.private_data_len = (u8)cm_node->pdata.size;
+ event.ird = cm_node->ird_size;
break;
case IW_CM_EVENT_CONNECT_REPLY:
i40iw_get_cmevent_info(cm_node, cm_id, &event);
@@ -335,13 +337,13 @@ static struct i40iw_cm_event *i40iw_create_event(struct i40iw_cm_node *cm_node,
*/
static void i40iw_free_retrans_entry(struct i40iw_cm_node *cm_node)
{
- struct i40iw_sc_dev *dev = cm_node->dev;
+ struct i40iw_device *iwdev = cm_node->iwdev;
struct i40iw_timer_entry *send_entry;
send_entry = cm_node->send_entry;
if (send_entry) {
cm_node->send_entry = NULL;
- i40iw_free_sqbuf(dev, (void *)send_entry->sqbuf);
+ i40iw_free_sqbuf(&iwdev->vsi, (void *)send_entry->sqbuf);
kfree(send_entry);
atomic_dec(&cm_node->ref_count);
}
@@ -360,15 +362,6 @@ static void i40iw_cleanup_retrans_entry(struct i40iw_cm_node *cm_node)
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
}
-static bool is_remote_ne020_or_chelsio(struct i40iw_cm_node *cm_node)
-{
- if ((cm_node->rem_mac[0] == 0x0) &&
- (((cm_node->rem_mac[1] == 0x12) && (cm_node->rem_mac[2] == 0x55)) ||
- ((cm_node->rem_mac[1] == 0x07 && (cm_node->rem_mac[2] == 0x43)))))
- return true;
- return false;
-}
-
/**
* i40iw_form_cm_frame - get a free packet and build frame
* @cm_node: connection's node ionfo to use in frame
@@ -384,7 +377,7 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
u8 flags)
{
struct i40iw_puda_buf *sqbuf;
- struct i40iw_sc_dev *dev = cm_node->dev;
+ struct i40iw_sc_vsi *vsi = &cm_node->iwdev->vsi;
u8 *buf;
struct tcphdr *tcph;
@@ -396,8 +389,9 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
u32 opts_len = 0;
u32 pd_len = 0;
u32 hdr_len = 0;
+ u16 vtag;
- sqbuf = i40iw_puda_get_bufpool(dev->ilq);
+ sqbuf = i40iw_puda_get_bufpool(vsi->ilq);
if (!sqbuf)
return NULL;
buf = sqbuf->mem.va;
@@ -408,11 +402,8 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
if (hdr)
hdr_len = hdr->size;
- if (pdata) {
+ if (pdata)
pd_len = pdata->size;
- if (!is_remote_ne020_or_chelsio(cm_node))
- pd_len += MPA_ZERO_PAD_LEN;
- }
if (cm_node->vlan_id < VLAN_TAG_PRESENT)
eth_hlen += 4;
@@ -445,7 +436,8 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
ether_addr_copy(ethh->h_source, cm_node->loc_mac);
if (cm_node->vlan_id < VLAN_TAG_PRESENT) {
((struct vlan_ethhdr *)ethh)->h_vlan_proto = htons(ETH_P_8021Q);
- ((struct vlan_ethhdr *)ethh)->h_vlan_TCI = htons(cm_node->vlan_id);
+ vtag = (cm_node->user_pri << VLAN_PRIO_SHIFT) | cm_node->vlan_id;
+ ((struct vlan_ethhdr *)ethh)->h_vlan_TCI = htons(vtag);
((struct vlan_ethhdr *)ethh)->h_vlan_encapsulated_proto = htons(ETH_P_IP);
} else {
@@ -454,7 +446,7 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
iph->version = IPVERSION;
iph->ihl = 5; /* 5 * 4Byte words, IP headr len */
- iph->tos = 0;
+ iph->tos = cm_node->tos;
iph->tot_len = htons(packetsize);
iph->id = htons(++cm_node->tcp_cntxt.loc_id);
@@ -474,13 +466,15 @@ static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
ether_addr_copy(ethh->h_source, cm_node->loc_mac);
if (cm_node->vlan_id < VLAN_TAG_PRESENT) {
((struct vlan_ethhdr *)ethh)->h_vlan_proto = htons(ETH_P_8021Q);
- ((struct vlan_ethhdr *)ethh)->h_vlan_TCI = htons(cm_node->vlan_id);
+ vtag = (cm_node->user_pri << VLAN_PRIO_SHIFT) | cm_node->vlan_id;
+ ((struct vlan_ethhdr *)ethh)->h_vlan_TCI = htons(vtag);
((struct vlan_ethhdr *)ethh)->h_vlan_encapsulated_proto = htons(ETH_P_IPV6);
} else {
ethh->h_proto = htons(ETH_P_IPV6);
}
ip6h->version = 6;
- ip6h->flow_lbl[0] = 0;
+ ip6h->priority = cm_node->tos >> 4;
+ ip6h->flow_lbl[0] = cm_node->tos << 4;
ip6h->flow_lbl[1] = 0;
ip6h->flow_lbl[2] = 0;
ip6h->payload_len = htons(packetsize - sizeof(*ip6h));
@@ -1065,7 +1059,7 @@ int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
int send_retrans,
int close_when_complete)
{
- struct i40iw_sc_dev *dev = cm_node->dev;
+ struct i40iw_sc_vsi *vsi = &cm_node->iwdev->vsi;
struct i40iw_cm_core *cm_core = cm_node->cm_core;
struct i40iw_timer_entry *new_send;
int ret = 0;
@@ -1074,7 +1068,7 @@ int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
if (!new_send) {
- i40iw_free_sqbuf(cm_node->dev, (void *)sqbuf);
+ i40iw_free_sqbuf(vsi, (void *)sqbuf);
return -ENOMEM;
}
new_send->retrycount = I40IW_DEFAULT_RETRYS;
@@ -1089,7 +1083,7 @@ int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
new_send->timetosend += (HZ / 10);
if (cm_node->close_entry) {
kfree(new_send);
- i40iw_free_sqbuf(cm_node->dev, (void *)sqbuf);
+ i40iw_free_sqbuf(vsi, (void *)sqbuf);
i40iw_pr_err("already close entry\n");
return -EINVAL;
}
@@ -1104,7 +1098,7 @@ int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
new_send->timetosend = jiffies + I40IW_RETRY_TIMEOUT;
atomic_inc(&sqbuf->refcount);
- i40iw_puda_send_buf(dev->ilq, sqbuf);
+ i40iw_puda_send_buf(vsi->ilq, sqbuf);
if (!send_retrans) {
i40iw_cleanup_retrans_entry(cm_node);
if (close_when_complete)
@@ -1201,6 +1195,7 @@ static void i40iw_cm_timer_tick(unsigned long pass)
struct i40iw_cm_node *cm_node;
struct i40iw_timer_entry *send_entry, *close_entry;
struct list_head *list_core_temp;
+ struct i40iw_sc_vsi *vsi;
struct list_head *list_node;
struct i40iw_cm_core *cm_core = (struct i40iw_cm_core *)pass;
u32 settimer = 0;
@@ -1276,9 +1271,10 @@ static void i40iw_cm_timer_tick(unsigned long pass)
cm_node->cm_core->stats_pkt_retrans++;
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
+ vsi = &cm_node->iwdev->vsi;
dev = cm_node->dev;
atomic_inc(&send_entry->sqbuf->refcount);
- i40iw_puda_send_buf(dev->ilq, send_entry->sqbuf);
+ i40iw_puda_send_buf(vsi->ilq, send_entry->sqbuf);
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
if (send_entry->send_retrans) {
send_entry->retranscount--;
@@ -1379,10 +1375,11 @@ int i40iw_send_syn(struct i40iw_cm_node *cm_node, u32 sendack)
static void i40iw_send_ack(struct i40iw_cm_node *cm_node)
{
struct i40iw_puda_buf *sqbuf;
+ struct i40iw_sc_vsi *vsi = &cm_node->iwdev->vsi;
sqbuf = i40iw_form_cm_frame(cm_node, NULL, NULL, NULL, SET_ACK);
if (sqbuf)
- i40iw_puda_send_buf(cm_node->dev->ilq, sqbuf);
+ i40iw_puda_send_buf(vsi->ilq, sqbuf);
else
i40iw_pr_err("no sqbuf\n");
}
@@ -1564,9 +1561,15 @@ static enum i40iw_status_code i40iw_del_multiple_qhash(
memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
sizeof(cm_info->loc_addr));
cm_info->vlan_id = child_listen_node->vlan_id;
- ret = i40iw_manage_qhash(iwdev, cm_info,
- I40IW_QHASH_TYPE_TCP_SYN,
- I40IW_QHASH_MANAGE_TYPE_DELETE, NULL, false);
+ if (child_listen_node->qhash_set) {
+ ret = i40iw_manage_qhash(iwdev, cm_info,
+ I40IW_QHASH_TYPE_TCP_SYN,
+ I40IW_QHASH_MANAGE_TYPE_DELETE,
+ NULL, false);
+ child_listen_node->qhash_set = false;
+ } else {
+ ret = I40IW_SUCCESS;
+ }
i40iw_debug(&iwdev->sc_dev,
I40IW_DEBUG_CM,
"freed pointer = %p\n",
@@ -1591,9 +1594,10 @@ static enum i40iw_status_code i40iw_del_multiple_qhash(
static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id, u8 *mac)
{
struct net_device *ip_dev = NULL;
-#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr laddr6;
+ if (!IS_ENABLED(CONFIG_IPV6))
+ return NULL;
i40iw_copy_ip_htonl(laddr6.in6_u.u6_addr32, addr);
if (vlan_id)
*vlan_id = I40IW_NO_VLAN;
@@ -1610,7 +1614,6 @@ static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id, u8 *ma
}
}
rcu_read_unlock();
-#endif
return ip_dev;
}
@@ -1646,7 +1649,7 @@ static enum i40iw_status_code i40iw_add_mqh_6(struct i40iw_device *iwdev,
{
struct net_device *ip_dev;
struct inet6_dev *idev;
- struct inet6_ifaddr *ifp;
+ struct inet6_ifaddr *ifp, *tmp;
enum i40iw_status_code ret = 0;
struct i40iw_cm_listener *child_listen_node;
unsigned long flags;
@@ -1661,7 +1664,7 @@ static enum i40iw_status_code i40iw_add_mqh_6(struct i40iw_device *iwdev,
i40iw_pr_err("idev == NULL\n");
break;
}
- list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) {
i40iw_debug(&iwdev->sc_dev,
I40IW_DEBUG_CM,
"IP=%pI6, vlan_id=%d, MAC=%pM\n",
@@ -1675,7 +1678,6 @@ static enum i40iw_status_code i40iw_add_mqh_6(struct i40iw_device *iwdev,
"Allocating child listener %p\n",
child_listen_node);
if (!child_listen_node) {
- i40iw_pr_err("listener memory allocation\n");
ret = I40IW_ERR_NO_MEMORY;
goto exit;
}
@@ -1695,6 +1697,7 @@ static enum i40iw_status_code i40iw_add_mqh_6(struct i40iw_device *iwdev,
I40IW_QHASH_MANAGE_TYPE_ADD,
NULL, true);
if (!ret) {
+ child_listen_node->qhash_set = true;
spin_lock_irqsave(&iwdev->cm_core.listen_list_lock, flags);
list_add(&child_listen_node->child_listen_list,
&cm_parent_listen_node->child_listen_list);
@@ -1751,7 +1754,6 @@ static enum i40iw_status_code i40iw_add_mqh_4(
"Allocating child listener %p\n",
child_listen_node);
if (!child_listen_node) {
- i40iw_pr_err("listener memory allocation\n");
in_dev_put(idev);
ret = I40IW_ERR_NO_MEMORY;
goto exit;
@@ -1773,6 +1775,7 @@ static enum i40iw_status_code i40iw_add_mqh_4(
NULL,
true);
if (!ret) {
+ child_listen_node->qhash_set = true;
spin_lock_irqsave(&iwdev->cm_core.listen_list_lock, flags);
list_add(&child_listen_node->child_listen_list,
&cm_parent_listen_node->child_listen_list);
@@ -1880,6 +1883,7 @@ static int i40iw_dec_refcnt_listen(struct i40iw_cm_core *cm_core,
nfo.loc_port = listener->loc_port;
nfo.ipv4 = listener->ipv4;
nfo.vlan_id = listener->vlan_id;
+ nfo.user_pri = listener->user_pri;
if (!list_empty(&listener->child_listen_list)) {
i40iw_del_multiple_qhash(listener->iwdev, &nfo, listener);
@@ -2138,6 +2142,20 @@ static struct i40iw_cm_node *i40iw_make_cm_node(
/* set our node specific transport info */
cm_node->ipv4 = cm_info->ipv4;
cm_node->vlan_id = cm_info->vlan_id;
+ if ((cm_node->vlan_id == I40IW_NO_VLAN) && iwdev->dcb)
+ cm_node->vlan_id = 0;
+ cm_node->tos = cm_info->tos;
+ cm_node->user_pri = cm_info->user_pri;
+ if (listener) {
+ if (listener->tos != cm_info->tos)
+ i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB,
+ "application TOS[%d] and remote client TOS[%d] mismatch\n",
+ listener->tos, cm_info->tos);
+ cm_node->tos = max(listener->tos, cm_info->tos);
+ cm_node->user_pri = rt_tos2priority(cm_node->tos);
+ i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "listener: TOS:[%d] UP:[%d]\n",
+ cm_node->tos, cm_node->user_pri);
+ }
memcpy(cm_node->loc_addr, cm_info->loc_addr, sizeof(cm_node->loc_addr));
memcpy(cm_node->rem_addr, cm_info->rem_addr, sizeof(cm_node->rem_addr));
cm_node->loc_port = cm_info->loc_port;
@@ -2162,7 +2180,7 @@ static struct i40iw_cm_node *i40iw_make_cm_node(
I40IW_CM_DEFAULT_RCV_WND_SCALED >> I40IW_CM_DEFAULT_RCV_WND_SCALE;
ts = current_kernel_time();
cm_node->tcp_cntxt.loc_seq_num = ts.tv_nsec;
- cm_node->tcp_cntxt.mss = iwdev->mss;
+ cm_node->tcp_cntxt.mss = iwdev->vsi.mss;
cm_node->iwdev = iwdev;
cm_node->dev = &iwdev->sc_dev;
@@ -2236,7 +2254,7 @@ static void i40iw_rem_ref_cm_node(struct i40iw_cm_node *cm_node)
i40iw_dec_refcnt_listen(cm_core, cm_node->listener, 0, true);
} else {
if (!i40iw_listen_port_in_use(cm_core, cm_node->loc_port) &&
- cm_node->apbvt_set && cm_node->iwdev) {
+ cm_node->apbvt_set) {
i40iw_manage_apbvt(cm_node->iwdev,
cm_node->loc_port,
I40IW_MANAGE_APBVT_DEL);
@@ -2861,7 +2879,7 @@ static struct i40iw_cm_node *i40iw_create_cm_node(
/* create a CM connection node */
cm_node = i40iw_make_cm_node(cm_core, iwdev, cm_info, NULL);
if (!cm_node)
- return NULL;
+ return ERR_PTR(-ENOMEM);
/* set our node side to client (active) side */
cm_node->tcp_cntxt.client = 1;
cm_node->tcp_cntxt.rcv_wscale = I40IW_CM_DEFAULT_RCV_WND_SCALE;
@@ -2874,7 +2892,8 @@ static struct i40iw_cm_node *i40iw_create_cm_node(
cm_node->vlan_id,
I40IW_CM_LISTENER_ACTIVE_STATE);
if (!loopback_remotelistener) {
- i40iw_create_event(cm_node, I40IW_CM_EVENT_ABORTED);
+ i40iw_rem_ref_cm_node(cm_node);
+ return ERR_PTR(-ECONNREFUSED);
} else {
loopback_cm_info = *cm_info;
loopback_cm_info.loc_port = cm_info->rem_port;
@@ -2887,7 +2906,7 @@ static struct i40iw_cm_node *i40iw_create_cm_node(
loopback_remotelistener);
if (!loopback_remotenode) {
i40iw_rem_ref_cm_node(cm_node);
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
cm_core->stats_loopbacks++;
loopback_remotenode->loopbackpartner = cm_node;
@@ -3041,10 +3060,10 @@ static int i40iw_cm_close(struct i40iw_cm_node *cm_node)
/**
* i40iw_receive_ilq - recv an ETHERNET packet, and process it
* through CM
- * @dev: FPK dev struct
+ * @vsi: pointer to the vsi structure
* @rbuf: receive buffer
*/
-void i40iw_receive_ilq(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *rbuf)
+void i40iw_receive_ilq(struct i40iw_sc_vsi *vsi, struct i40iw_puda_buf *rbuf)
{
struct i40iw_cm_node *cm_node;
struct i40iw_cm_listener *listener;
@@ -3052,9 +3071,11 @@ void i40iw_receive_ilq(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *rbuf)
struct ipv6hdr *ip6h;
struct tcphdr *tcph;
struct i40iw_cm_info cm_info;
+ struct i40iw_sc_dev *dev = vsi->dev;
struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
struct i40iw_cm_core *cm_core = &iwdev->cm_core;
struct vlan_ethhdr *ethh;
+ u16 vtag;
/* if vlan, then maclen = 18 else 14 */
iph = (struct iphdr *)rbuf->iph;
@@ -3068,7 +3089,9 @@ void i40iw_receive_ilq(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *rbuf)
ethh = (struct vlan_ethhdr *)rbuf->mem.va;
if (ethh->h_vlan_proto == htons(ETH_P_8021Q)) {
- cm_info.vlan_id = ntohs(ethh->h_vlan_TCI) & VLAN_VID_MASK;
+ vtag = ntohs(ethh->h_vlan_TCI);
+ cm_info.user_pri = (vtag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+ cm_info.vlan_id = vtag & VLAN_VID_MASK;
i40iw_debug(cm_core->dev,
I40IW_DEBUG_CM,
"%s vlan_id=%d\n",
@@ -3083,6 +3106,7 @@ void i40iw_receive_ilq(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *rbuf)
cm_info.loc_addr[0] = ntohl(iph->daddr);
cm_info.rem_addr[0] = ntohl(iph->saddr);
cm_info.ipv4 = true;
+ cm_info.tos = iph->tos;
} else {
ip6h = (struct ipv6hdr *)rbuf->iph;
i40iw_copy_ip_ntohl(cm_info.loc_addr,
@@ -3090,6 +3114,7 @@ void i40iw_receive_ilq(struct i40iw_sc_dev *dev, struct i40iw_puda_buf *rbuf)
i40iw_copy_ip_ntohl(cm_info.rem_addr,
ip6h->saddr.in6_u.u6_addr32);
cm_info.ipv4 = false;
+ cm_info.tos = (ip6h->priority << 4) | (ip6h->flow_lbl[0] >> 4);
}
cm_info.loc_port = ntohs(tcph->dest);
cm_info.rem_port = ntohs(tcph->source);
@@ -3309,6 +3334,8 @@ static void i40iw_cm_init_tsa_conn(struct i40iw_qp *iwqp,
ctx_info->tcp_info_valid = true;
ctx_info->iwarp_info_valid = true;
+ ctx_info->add_to_qoslist = true;
+ ctx_info->user_pri = cm_node->user_pri;
i40iw_init_tcp_ctx(cm_node, &tcp_info, iwqp);
if (cm_node->snd_mark_en) {
@@ -3320,33 +3347,47 @@ static void i40iw_cm_init_tsa_conn(struct i40iw_qp *iwqp,
cm_node->state = I40IW_CM_STATE_OFFLOADED;
tcp_info.tcp_state = I40IW_TCP_STATE_ESTABLISHED;
tcp_info.src_mac_addr_idx = iwdev->mac_ip_table_idx;
+ tcp_info.tos = cm_node->tos;
dev->iw_priv_qp_ops->qp_setctx(&iwqp->sc_qp, (u64 *)(iwqp->host_ctx.va), ctx_info);
/* once tcp_info is set, no need to do it again */
ctx_info->tcp_info_valid = false;
ctx_info->iwarp_info_valid = false;
+ ctx_info->add_to_qoslist = false;
}
/**
* i40iw_cm_disconn - when a connection is being closed
* @iwqp: associate qp for the connection
*/
-int i40iw_cm_disconn(struct i40iw_qp *iwqp)
+void i40iw_cm_disconn(struct i40iw_qp *iwqp)
{
struct disconn_work *work;
struct i40iw_device *iwdev = iwqp->iwdev;
struct i40iw_cm_core *cm_core = &iwdev->cm_core;
+ unsigned long flags;
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work)
- return -ENOMEM; /* Timer will clean up */
-
+ return; /* Timer will clean up */
+
+ spin_lock_irqsave(&iwdev->qptable_lock, flags);
+ if (!iwdev->qp_table[iwqp->ibqp.qp_num]) {
+ spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
+ i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM,
+ "%s qp_id %d is already freed\n",
+ __func__, iwqp->ibqp.qp_num);
+ kfree(work);
+ return;
+ }
i40iw_add_ref(&iwqp->ibqp);
+ spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
+
work->iwqp = iwqp;
INIT_WORK(&work->work, i40iw_disconnect_worker);
queue_work(cm_core->disconn_wq, &work->work);
- return 0;
+ return;
}
/**
@@ -3432,7 +3473,7 @@ static void i40iw_cm_disconn_true(struct i40iw_qp *iwqp)
*terminate-handler to issue cm_disconn which can re-free
*a QP even after its refcnt=0.
*/
- del_timer(&iwqp->terminate_timer);
+ i40iw_terminate_del_timer(qp);
if (!iwqp->flush_issued) {
iwqp->flush_issued = 1;
issue_flush = 1;
@@ -3462,7 +3503,7 @@ static void i40iw_cm_disconn_true(struct i40iw_qp *iwqp)
/* Flush the queues */
i40iw_flush_wqes(iwdev, iwqp);
- if (qp->term_flags) {
+ if (qp->term_flags && iwqp->ibqp.event_handler) {
ibevent.device = iwqp->ibqp.device;
ibevent.event = (qp->eventtype == TERM_EVENT_QP_FATAL) ?
IB_EVENT_QP_FATAL : IB_EVENT_QP_ACCESS_ERR;
@@ -3571,7 +3612,7 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
iwqp->cm_node = (void *)cm_node;
cm_node->iwqp = iwqp;
- buf_len = conn_param->private_data_len + I40IW_MAX_IETF_SIZE + MPA_ZERO_PAD_LEN;
+ buf_len = conn_param->private_data_len + I40IW_MAX_IETF_SIZE;
status = i40iw_allocate_dma_mem(dev->hw, &iwqp->ietf_mem, buf_len, 1);
@@ -3605,18 +3646,10 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
iwqp->lsmm_mr = ibmr;
if (iwqp->page)
iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
- if (is_remote_ne020_or_chelsio(cm_node))
- dev->iw_priv_qp_ops->qp_send_lsmm(
- &iwqp->sc_qp,
+ dev->iw_priv_qp_ops->qp_send_lsmm(&iwqp->sc_qp,
iwqp->ietf_mem.va,
(accept.size + conn_param->private_data_len),
ibmr->lkey);
- else
- dev->iw_priv_qp_ops->qp_send_lsmm(
- &iwqp->sc_qp,
- iwqp->ietf_mem.va,
- (accept.size + conn_param->private_data_len + MPA_ZERO_PAD_LEN),
- ibmr->lkey);
} else {
if (iwqp->page)
@@ -3714,6 +3747,7 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
struct sockaddr_in6 *raddr6;
bool qhash_set = false;
int apbvt_set = 0;
+ int err = 0;
enum i40iw_status_code status;
ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn);
@@ -3759,6 +3793,10 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
i40iw_netdev_vlan_ipv6(cm_info.loc_addr, &cm_info.vlan_id, NULL);
}
cm_info.cm_id = cm_id;
+ cm_info.tos = cm_id->tos;
+ cm_info.user_pri = rt_tos2priority(cm_id->tos);
+ i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "%s TOS:[%d] UP:[%d]\n",
+ __func__, cm_id->tos, cm_info.user_pri);
if ((cm_info.ipv4 && (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr)) ||
(!cm_info.ipv4 && memcmp(laddr6->sin6_addr.in6_u.u6_addr32,
raddr6->sin6_addr.in6_u.u6_addr32,
@@ -3790,8 +3828,11 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
conn_param->private_data_len,
(void *)conn_param->private_data,
&cm_info);
- if (!cm_node)
- goto err;
+
+ if (IS_ERR(cm_node)) {
+ err = PTR_ERR(cm_node);
+ goto err_out;
+ }
i40iw_record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord);
if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO &&
@@ -3805,10 +3846,12 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
iwqp->cm_id = cm_id;
i40iw_add_ref(&iwqp->ibqp);
- if (cm_node->state == I40IW_CM_STATE_SYN_SENT) {
- if (i40iw_send_syn(cm_node, 0)) {
+ if (cm_node->state != I40IW_CM_STATE_OFFLOADED) {
+ cm_node->state = I40IW_CM_STATE_SYN_SENT;
+ err = i40iw_send_syn(cm_node, 0);
+ if (err) {
i40iw_rem_ref_cm_node(cm_node);
- goto err;
+ goto err_out;
}
}
@@ -3820,24 +3863,25 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
cm_node->cm_id);
return 0;
-err:
- if (cm_node) {
- if (cm_node->ipv4)
- i40iw_debug(cm_node->dev,
- I40IW_DEBUG_CM,
- "Api - connect() FAILED: dest addr=%pI4",
- cm_node->rem_addr);
- else
- i40iw_debug(cm_node->dev, I40IW_DEBUG_CM,
- "Api - connect() FAILED: dest addr=%pI6",
- cm_node->rem_addr);
- }
- i40iw_manage_qhash(iwdev,
- &cm_info,
- I40IW_QHASH_TYPE_TCP_ESTABLISHED,
- I40IW_QHASH_MANAGE_TYPE_DELETE,
- NULL,
- false);
+err_out:
+ if (cm_info.ipv4)
+ i40iw_debug(&iwdev->sc_dev,
+ I40IW_DEBUG_CM,
+ "Api - connect() FAILED: dest addr=%pI4",
+ cm_info.rem_addr);
+ else
+ i40iw_debug(&iwdev->sc_dev,
+ I40IW_DEBUG_CM,
+ "Api - connect() FAILED: dest addr=%pI6",
+ cm_info.rem_addr);
+
+ if (qhash_set)
+ i40iw_manage_qhash(iwdev,
+ &cm_info,
+ I40IW_QHASH_TYPE_TCP_ESTABLISHED,
+ I40IW_QHASH_MANAGE_TYPE_DELETE,
+ NULL,
+ false);
if (apbvt_set && !i40iw_listen_port_in_use(&iwdev->cm_core,
cm_info.loc_port))
@@ -3846,7 +3890,7 @@ err:
I40IW_MANAGE_APBVT_DEL);
cm_id->rem_ref(cm_id);
iwdev->cm_core.stats_connect_errs++;
- return -ENOMEM;
+ return err;
}
/**
@@ -3904,6 +3948,10 @@ int i40iw_create_listen(struct iw_cm_id *cm_id, int backlog)
cm_id->provider_data = cm_listen_node;
+ cm_listen_node->tos = cm_id->tos;
+ cm_listen_node->user_pri = rt_tos2priority(cm_id->tos);
+ cm_info.user_pri = cm_listen_node->user_pri;
+
if (!cm_listen_node->reused_node) {
if (wildcard) {
if (cm_info.ipv4)
@@ -4124,3 +4172,158 @@ static void i40iw_cm_post_event(struct i40iw_cm_event *event)
queue_work(event->cm_node->cm_core->event_wq, &event->event_work);
}
+
+/**
+ * i40iw_qhash_ctrl - enable/disable qhash for list
+ * @iwdev: device pointer
+ * @parent_listen_node: parent listen node
+ * @nfo: cm info node
+ * @ipaddr: Pointer to IPv4 or IPv6 address
+ * @ipv4: flag indicating IPv4 when true
+ * @ifup: flag indicating interface up when true
+ *
+ * Enables or disables the qhash for the node in the child
+ * listen list that matches ipaddr. If no matching IP was found
+ * it will allocate and add a new child listen node to the
+ * parent listen node. The listen_list_lock is assumed to be
+ * held when called.
+ */
+static void i40iw_qhash_ctrl(struct i40iw_device *iwdev,
+ struct i40iw_cm_listener *parent_listen_node,
+ struct i40iw_cm_info *nfo,
+ u32 *ipaddr, bool ipv4, bool ifup)
+{
+ struct list_head *child_listen_list = &parent_listen_node->child_listen_list;
+ struct i40iw_cm_listener *child_listen_node;
+ struct list_head *pos, *tpos;
+ enum i40iw_status_code ret;
+ bool node_allocated = false;
+ enum i40iw_quad_hash_manage_type op =
+ ifup ? I40IW_QHASH_MANAGE_TYPE_ADD : I40IW_QHASH_MANAGE_TYPE_DELETE;
+
+ list_for_each_safe(pos, tpos, child_listen_list) {
+ child_listen_node =
+ list_entry(pos,
+ struct i40iw_cm_listener,
+ child_listen_list);
+ if (!memcmp(child_listen_node->loc_addr, ipaddr, ipv4 ? 4 : 16))
+ goto set_qhash;
+ }
+
+ /* if not found then add a child listener if interface is going up */
+ if (!ifup)
+ return;
+ child_listen_node = kzalloc(sizeof(*child_listen_node), GFP_ATOMIC);
+ if (!child_listen_node)
+ return;
+ node_allocated = true;
+ memcpy(child_listen_node, parent_listen_node, sizeof(*child_listen_node));
+
+ memcpy(child_listen_node->loc_addr, ipaddr, ipv4 ? 4 : 16);
+
+set_qhash:
+ memcpy(nfo->loc_addr,
+ child_listen_node->loc_addr,
+ sizeof(nfo->loc_addr));
+ nfo->vlan_id = child_listen_node->vlan_id;
+ ret = i40iw_manage_qhash(iwdev, nfo,
+ I40IW_QHASH_TYPE_TCP_SYN,
+ op,
+ NULL, false);
+ if (!ret) {
+ child_listen_node->qhash_set = ifup;
+ if (node_allocated)
+ list_add(&child_listen_node->child_listen_list,
+ &parent_listen_node->child_listen_list);
+ } else if (node_allocated) {
+ kfree(child_listen_node);
+ }
+}
+
+/**
+ * i40iw_cm_disconnect_all - disconnect all connected qp's
+ * @iwdev: device pointer
+ */
+void i40iw_cm_disconnect_all(struct i40iw_device *iwdev)
+{
+ struct i40iw_cm_core *cm_core = &iwdev->cm_core;
+ struct list_head *list_core_temp;
+ struct list_head *list_node;
+ struct i40iw_cm_node *cm_node;
+ unsigned long flags;
+ struct list_head connected_list;
+ struct ib_qp_attr attr;
+
+ INIT_LIST_HEAD(&connected_list);
+ spin_lock_irqsave(&cm_core->ht_lock, flags);
+ list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) {
+ cm_node = container_of(list_node, struct i40iw_cm_node, list);
+ atomic_inc(&cm_node->ref_count);
+ list_add(&cm_node->connected_entry, &connected_list);
+ }
+ spin_unlock_irqrestore(&cm_core->ht_lock, flags);
+
+ list_for_each_safe(list_node, list_core_temp, &connected_list) {
+ cm_node = container_of(list_node, struct i40iw_cm_node, connected_entry);
+ attr.qp_state = IB_QPS_ERR;
+ i40iw_modify_qp(&cm_node->iwqp->ibqp, &attr, IB_QP_STATE, NULL);
+ i40iw_rem_ref_cm_node(cm_node);
+ }
+}
+
+/**
+ * i40iw_ifdown_notify - process an ifdown on an interface
+ * @iwdev: device pointer
+ * @ipaddr: Pointer to IPv4 or IPv6 address
+ * @ipv4: flag indicating IPv4 when true
+ * @ifup: flag indicating interface up when true
+ */
+void i40iw_if_notify(struct i40iw_device *iwdev, struct net_device *netdev,
+ u32 *ipaddr, bool ipv4, bool ifup)
+{
+ struct i40iw_cm_core *cm_core = &iwdev->cm_core;
+ unsigned long flags;
+ struct i40iw_cm_listener *listen_node;
+ static const u32 ip_zero[4] = { 0, 0, 0, 0 };
+ struct i40iw_cm_info nfo;
+ u16 vlan_id = rdma_vlan_dev_vlan_id(netdev);
+ enum i40iw_status_code ret;
+ enum i40iw_quad_hash_manage_type op =
+ ifup ? I40IW_QHASH_MANAGE_TYPE_ADD : I40IW_QHASH_MANAGE_TYPE_DELETE;
+
+ /* Disable or enable qhash for listeners */
+ spin_lock_irqsave(&cm_core->listen_list_lock, flags);
+ list_for_each_entry(listen_node, &cm_core->listen_nodes, list) {
+ if (vlan_id == listen_node->vlan_id &&
+ (!memcmp(listen_node->loc_addr, ipaddr, ipv4 ? 4 : 16) ||
+ !memcmp(listen_node->loc_addr, ip_zero, ipv4 ? 4 : 16))) {
+ memcpy(nfo.loc_addr, listen_node->loc_addr,
+ sizeof(nfo.loc_addr));
+ nfo.loc_port = listen_node->loc_port;
+ nfo.ipv4 = listen_node->ipv4;
+ nfo.vlan_id = listen_node->vlan_id;
+ nfo.user_pri = listen_node->user_pri;
+ if (!list_empty(&listen_node->child_listen_list)) {
+ i40iw_qhash_ctrl(iwdev,
+ listen_node,
+ &nfo,
+ ipaddr, ipv4, ifup);
+ } else if (memcmp(listen_node->loc_addr, ip_zero,
+ ipv4 ? 4 : 16)) {
+ ret = i40iw_manage_qhash(iwdev,
+ &nfo,
+ I40IW_QHASH_TYPE_TCP_SYN,
+ op,
+ NULL,
+ false);
+ if (!ret)
+ listen_node->qhash_set = ifup;
+ }
+ }
+ }
+ spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
+
+ /* disconnect any connected qp's on ifdown */
+ if (!ifup)
+ i40iw_cm_disconnect_all(iwdev);
+}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.h b/drivers/infiniband/hw/i40iw/i40iw_cm.h
index e9046d9f9645..2e52e38ffcf3 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_cm.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_cm.h
@@ -56,8 +56,6 @@
#define I40IW_MAX_IETF_SIZE 32
-#define MPA_ZERO_PAD_LEN 4
-
/* IETF RTR MSG Fields */
#define IETF_PEER_TO_PEER 0x8000
#define IETF_FLPDU_ZERO_LEN 0x4000
@@ -299,6 +297,7 @@ struct i40iw_cm_listener {
enum i40iw_cm_listener_state listener_state;
u32 reused_node;
u8 user_pri;
+ u8 tos;
u16 vlan_id;
bool qhash_set;
bool ipv4;
@@ -341,9 +340,11 @@ struct i40iw_cm_node {
int accept_pend;
struct list_head timer_entry;
struct list_head reset_entry;
+ struct list_head connected_entry;
atomic_t passive_state;
bool qhash_set;
u8 user_pri;
+ u8 tos;
bool ipv4;
bool snd_mark_en;
u16 lsmm_size;
@@ -368,7 +369,8 @@ struct i40iw_cm_info {
u32 rem_addr[4];
u16 vlan_id;
int backlog;
- u16 user_pri;
+ u8 user_pri;
+ u8 tos;
bool ipv4;
};
@@ -445,4 +447,7 @@ int i40iw_arp_table(struct i40iw_device *iwdev,
u8 *mac_addr,
u32 action);
+void i40iw_if_notify(struct i40iw_device *iwdev, struct net_device *netdev,
+ u32 *ipaddr, bool ipv4, bool ifup);
+void i40iw_cm_disconnect_all(struct i40iw_device *iwdev);
#endif /* I40IW_CM_H */
diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
index 2c4b4d072d6a..392f78384a60 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
@@ -103,6 +103,7 @@ static enum i40iw_status_code i40iw_cqp_poll_registers(
if (newtail != tail) {
/* SUCCESS */
I40IW_RING_MOVE_TAIL(cqp->sq_ring);
+ cqp->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]++;
return 0;
}
udelay(I40IW_SLEEP_COUNT);
@@ -223,6 +224,136 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_query_buf(
}
/**
+ * i40iw_fill_qos_list - Change all unknown qs handles to available ones
+ * @qs_list: list of qs_handles to be fixed with valid qs_handles
+ */
+static void i40iw_fill_qos_list(u16 *qs_list)
+{
+ u16 qshandle = qs_list[0];
+ int i;
+
+ for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) {
+ if (qs_list[i] == QS_HANDLE_UNKNOWN)
+ qs_list[i] = qshandle;
+ else
+ qshandle = qs_list[i];
+ }
+}
+
+/**
+ * i40iw_qp_from_entry - Given entry, get to the qp structure
+ * @entry: Points to list of qp structure
+ */
+static struct i40iw_sc_qp *i40iw_qp_from_entry(struct list_head *entry)
+{
+ if (!entry)
+ return NULL;
+
+ return (struct i40iw_sc_qp *)((char *)entry - offsetof(struct i40iw_sc_qp, list));
+}
+
+/**
+ * i40iw_get_qp - get the next qp from the list given current qp
+ * @head: Listhead of qp's
+ * @qp: current qp
+ */
+static struct i40iw_sc_qp *i40iw_get_qp(struct list_head *head, struct i40iw_sc_qp *qp)
+{
+ struct list_head *entry = NULL;
+ struct list_head *lastentry;
+
+ if (list_empty(head))
+ return NULL;
+
+ if (!qp) {
+ entry = head->next;
+ } else {
+ lastentry = &qp->list;
+ entry = (lastentry != head) ? lastentry->next : NULL;
+ }
+
+ return i40iw_qp_from_entry(entry);
+}
+
+/**
+ * i40iw_change_l2params - given the new l2 parameters, change all qp
+ * @vsi: pointer to the vsi structure
+ * @l2params: New paramaters from l2
+ */
+void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2params)
+{
+ struct i40iw_sc_dev *dev = vsi->dev;
+ struct i40iw_sc_qp *qp = NULL;
+ bool qs_handle_change = false;
+ bool mss_change = false;
+ unsigned long flags;
+ u16 qs_handle;
+ int i;
+
+ if (vsi->mss != l2params->mss) {
+ mss_change = true;
+ vsi->mss = l2params->mss;
+ }
+
+ i40iw_fill_qos_list(l2params->qs_handle_list);
+ for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) {
+ qs_handle = l2params->qs_handle_list[i];
+ if (vsi->qos[i].qs_handle != qs_handle)
+ qs_handle_change = true;
+ else if (!mss_change)
+ continue; /* no MSS nor qs handle change */
+ spin_lock_irqsave(&vsi->qos[i].lock, flags);
+ qp = i40iw_get_qp(&vsi->qos[i].qplist, qp);
+ while (qp) {
+ if (mss_change)
+ i40iw_qp_mss_modify(dev, qp);
+ if (qs_handle_change) {
+ qp->qs_handle = qs_handle;
+ /* issue cqp suspend command */
+ i40iw_qp_suspend_resume(dev, qp, true);
+ }
+ qp = i40iw_get_qp(&vsi->qos[i].qplist, qp);
+ }
+ spin_unlock_irqrestore(&vsi->qos[i].lock, flags);
+ vsi->qos[i].qs_handle = qs_handle;
+ }
+}
+
+/**
+ * i40iw_qp_rem_qos - remove qp from qos lists during destroy qp
+ * @qp: qp to be removed from qos
+ */
+static void i40iw_qp_rem_qos(struct i40iw_sc_qp *qp)
+{
+ struct i40iw_sc_vsi *vsi = qp->vsi;
+ unsigned long flags;
+
+ if (!qp->on_qoslist)
+ return;
+ spin_lock_irqsave(&vsi->qos[qp->user_pri].lock, flags);
+ list_del(&qp->list);
+ spin_unlock_irqrestore(&vsi->qos[qp->user_pri].lock, flags);
+}
+
+/**
+ * i40iw_qp_add_qos - called during setctx fot qp to be added to qos
+ * @qp: qp to be added to qos
+ */
+void i40iw_qp_add_qos(struct i40iw_sc_qp *qp)
+{
+ struct i40iw_sc_vsi *vsi = qp->vsi;
+ unsigned long flags;
+
+ if (qp->on_qoslist)
+ return;
+ spin_lock_irqsave(&vsi->qos[qp->user_pri].lock, flags);
+ qp->qs_handle = vsi->qos[qp->user_pri].qs_handle;
+ list_add(&qp->list, &vsi->qos[qp->user_pri].qplist);
+ qp->on_qoslist = true;
+ spin_unlock_irqrestore(&vsi->qos[qp->user_pri].lock, flags);
+}
+
+/**
* i40iw_sc_pd_init - initialize sc pd struct
* @dev: sc device struct
* @pd: sc pd ptr
@@ -292,6 +423,9 @@ static enum i40iw_status_code i40iw_sc_cqp_init(struct i40iw_sc_cqp *cqp,
info->dev->cqp = cqp;
I40IW_RING_INIT(cqp->sq_ring, cqp->sq_size);
+ cqp->dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] = 0;
+ cqp->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS] = 0;
+
i40iw_debug(cqp->dev, I40IW_DEBUG_WQE,
"%s: sq_size[%04d] hw_sq_size[%04d] sq_base[%p] sq_pa[%llxh] cqp[%p] polarity[x%04X]\n",
__func__, cqp->sq_size, cqp->hw_sq_size,
@@ -302,12 +436,10 @@ static enum i40iw_status_code i40iw_sc_cqp_init(struct i40iw_sc_cqp *cqp,
/**
* i40iw_sc_cqp_create - create cqp during bringup
* @cqp: struct for cqp hw
- * @disable_pfpdus: if pfpdu to be disabled
* @maj_err: If error, major err number
* @min_err: If error, minor err number
*/
static enum i40iw_status_code i40iw_sc_cqp_create(struct i40iw_sc_cqp *cqp,
- bool disable_pfpdus,
u16 *maj_err,
u16 *min_err)
{
@@ -326,9 +458,6 @@ static enum i40iw_status_code i40iw_sc_cqp_create(struct i40iw_sc_cqp *cqp,
temp = LS_64(cqp->hw_sq_size, I40IW_CQPHC_SQSIZE) |
LS_64(cqp->struct_ver, I40IW_CQPHC_SVER);
- if (disable_pfpdus)
- temp |= LS_64(1, I40IW_CQPHC_DISABLE_PFPDUS);
-
set_64bit_val(cqp->host_ctx, 0, temp);
set_64bit_val(cqp->host_ctx, 8, cqp->sq_pa);
temp = LS_64(cqp->enabled_vf_count, I40IW_CQPHC_ENABLED_VFS) |
@@ -424,6 +553,7 @@ u64 *i40iw_sc_cqp_get_next_send_wqe(struct i40iw_sc_cqp *cqp, u64 scratch)
return NULL;
}
I40IW_ATOMIC_RING_MOVE_HEAD(cqp->sq_ring, wqe_idx, ret_code);
+ cqp->dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS]++;
if (ret_code)
return NULL;
if (!wqe_idx)
@@ -559,6 +689,8 @@ static enum i40iw_status_code i40iw_sc_ccq_get_cqe_info(
I40IW_RING_GETCURRENT_HEAD(ccq->cq_uk.cq_ring));
wmb(); /* write shadow area before tail */
I40IW_RING_MOVE_TAIL(cqp->sq_ring);
+ ccq->dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]++;
+
return ret_code;
}
@@ -1051,6 +1183,7 @@ static enum i40iw_status_code i40iw_sc_manage_qhash_table_entry(
u64 qw1 = 0;
u64 qw2 = 0;
u64 temp;
+ struct i40iw_sc_vsi *vsi = info->vsi;
wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
if (!wqe)
@@ -1082,7 +1215,7 @@ static enum i40iw_status_code i40iw_sc_manage_qhash_table_entry(
LS_64(info->dest_ip[2], I40IW_CQPSQ_QHASH_ADDR2) |
LS_64(info->dest_ip[3], I40IW_CQPSQ_QHASH_ADDR3));
}
- qw2 = LS_64(cqp->dev->qs_handle, I40IW_CQPSQ_QHASH_QS_HANDLE);
+ qw2 = LS_64(vsi->qos[info->user_pri].qs_handle, I40IW_CQPSQ_QHASH_QS_HANDLE);
if (info->vlan_valid)
qw2 |= LS_64(info->vlan_id, I40IW_CQPSQ_QHASH_VLANID);
set_64bit_val(wqe, 16, qw2);
@@ -2103,6 +2236,7 @@ static enum i40iw_status_code i40iw_sc_qp_init(struct i40iw_sc_qp *qp,
u32 offset;
qp->dev = info->pd->dev;
+ qp->vsi = info->vsi;
qp->sq_pa = info->sq_pa;
qp->rq_pa = info->rq_pa;
qp->hw_host_ctx_pa = info->host_ctx_pa;
@@ -2151,7 +2285,7 @@ static enum i40iw_status_code i40iw_sc_qp_init(struct i40iw_sc_qp *qp,
qp->rq_tph_en = info->rq_tph_en;
qp->rcv_tph_en = info->rcv_tph_en;
qp->xmit_tph_en = info->xmit_tph_en;
- qp->qs_handle = qp->pd->dev->qs_handle;
+ qp->qs_handle = qp->vsi->qos[qp->user_pri].qs_handle;
qp->exception_lan_queue = qp->pd->dev->exception_lan_queue;
return 0;
@@ -2296,6 +2430,7 @@ static enum i40iw_status_code i40iw_sc_qp_destroy(
struct i40iw_sc_cqp *cqp;
u64 header;
+ i40iw_qp_rem_qos(qp);
cqp = qp->pd->dev->cqp;
wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
if (!wqe)
@@ -2443,10 +2578,20 @@ static enum i40iw_status_code i40iw_sc_qp_setctx(
{
struct i40iwarp_offload_info *iw;
struct i40iw_tcp_offload_info *tcp;
+ struct i40iw_sc_vsi *vsi;
+ struct i40iw_sc_dev *dev;
u64 qw0, qw3, qw7 = 0;
iw = info->iwarp_info;
tcp = info->tcp_info;
+ vsi = qp->vsi;
+ dev = qp->dev;
+ if (info->add_to_qoslist) {
+ qp->user_pri = info->user_pri;
+ i40iw_qp_add_qos(qp);
+ i40iw_debug(qp->dev, I40IW_DEBUG_DCB, "%s qp[%d] UP[%d] qset[%d]\n",
+ __func__, qp->qp_uk.qp_id, qp->user_pri, qp->qs_handle);
+ }
qw0 = LS_64(qp->qp_uk.rq_wqe_size, I40IWQPC_RQWQESIZE) |
LS_64(info->err_rq_idx_valid, I40IWQPC_ERR_RQ_IDX_VALID) |
LS_64(qp->rcv_tph_en, I40IWQPC_RCVTPHEN) |
@@ -2487,16 +2632,14 @@ static enum i40iw_status_code i40iw_sc_qp_setctx(
LS_64(iw->rdmap_ver, I40IWQPC_RDMAP_VER);
qw7 |= LS_64(iw->pd_id, I40IWQPC_PDIDX);
- set_64bit_val(qp_ctx, 144, qp->q2_pa);
+ set_64bit_val(qp_ctx,
+ 144,
+ LS_64(qp->q2_pa, I40IWQPC_Q2ADDR) |
+ LS_64(vsi->fcn_id, I40IWQPC_STAT_INDEX));
set_64bit_val(qp_ctx,
152,
LS_64(iw->last_byte_sent, I40IWQPC_LASTBYTESENT));
- /*
- * Hard-code IRD_SIZE to hw-limit, 128, in qpctx, i.e matching an
- *advertisable IRD of 64
- */
- iw->ird_size = I40IW_QPCTX_ENCD_MAXIRD;
set_64bit_val(qp_ctx,
160,
LS_64(iw->ord_size, I40IWQPC_ORDSIZE) |
@@ -2507,6 +2650,9 @@ static enum i40iw_status_code i40iw_sc_qp_setctx(
LS_64(iw->bind_en, I40IWQPC_BINDEN) |
LS_64(iw->fast_reg_en, I40IWQPC_FASTREGEN) |
LS_64(iw->priv_mode_en, I40IWQPC_PRIVEN) |
+ LS_64((((vsi->stats_fcn_id_alloc) &&
+ (dev->is_pf) && (vsi->fcn_id >= I40IW_FIRST_NON_PF_STAT)) ? 1 : 0),
+ I40IWQPC_USESTATSINSTANCE) |
LS_64(1, I40IWQPC_IWARPMODE) |
LS_64(iw->rcv_mark_en, I40IWQPC_RCVMARKERS) |
LS_64(iw->align_hdrs, I40IWQPC_ALIGNHDRS) |
@@ -2623,7 +2769,9 @@ static enum i40iw_status_code i40iw_sc_alloc_stag(
u64 *wqe;
struct i40iw_sc_cqp *cqp;
u64 header;
+ enum i40iw_page_size page_size;
+ page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K;
cqp = dev->cqp;
wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
if (!wqe)
@@ -2643,7 +2791,7 @@ static enum i40iw_status_code i40iw_sc_alloc_stag(
LS_64(1, I40IW_CQPSQ_STAG_MR) |
LS_64(info->access_rights, I40IW_CQPSQ_STAG_ARIGHTS) |
LS_64(info->chunk_size, I40IW_CQPSQ_STAG_LPBLSIZE) |
- LS_64(info->page_size, I40IW_CQPSQ_STAG_HPAGESIZE) |
+ LS_64(page_size, I40IW_CQPSQ_STAG_HPAGESIZE) |
LS_64(info->remote_access, I40IW_CQPSQ_STAG_REMACCENABLED) |
LS_64(info->use_hmc_fcn_index, I40IW_CQPSQ_STAG_USEHMCFNIDX) |
LS_64(info->use_pf_rid, I40IW_CQPSQ_STAG_USEPFRID) |
@@ -2679,7 +2827,9 @@ static enum i40iw_status_code i40iw_sc_mr_reg_non_shared(
u32 pble_obj_cnt;
bool remote_access;
u8 addr_type;
+ enum i40iw_page_size page_size;
+ page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K;
if (info->access_rights & (I40IW_ACCESS_FLAGS_REMOTEREAD_ONLY |
I40IW_ACCESS_FLAGS_REMOTEWRITE_ONLY))
remote_access = true;
@@ -2722,7 +2872,7 @@ static enum i40iw_status_code i40iw_sc_mr_reg_non_shared(
header = LS_64(I40IW_CQP_OP_REG_MR, I40IW_CQPSQ_OPCODE) |
LS_64(1, I40IW_CQPSQ_STAG_MR) |
LS_64(info->chunk_size, I40IW_CQPSQ_STAG_LPBLSIZE) |
- LS_64(info->page_size, I40IW_CQPSQ_STAG_HPAGESIZE) |
+ LS_64(page_size, I40IW_CQPSQ_STAG_HPAGESIZE) |
LS_64(info->access_rights, I40IW_CQPSQ_STAG_ARIGHTS) |
LS_64(remote_access, I40IW_CQPSQ_STAG_REMACCENABLED) |
LS_64(addr_type, I40IW_CQPSQ_STAG_VABASEDTO) |
@@ -2937,7 +3087,9 @@ enum i40iw_status_code i40iw_sc_mr_fast_register(
u64 temp, header;
u64 *wqe;
u32 wqe_idx;
+ enum i40iw_page_size page_size;
+ page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K;
wqe = i40iw_qp_get_next_send_wqe(&qp->qp_uk, &wqe_idx, I40IW_QP_WQE_MIN_SIZE,
0, info->wr_id);
if (!wqe)
@@ -2964,7 +3116,7 @@ enum i40iw_status_code i40iw_sc_mr_fast_register(
LS_64(info->stag_idx, I40IWQPSQ_STAGINDEX) |
LS_64(I40IWQP_OP_FAST_REGISTER, I40IWQPSQ_OPCODE) |
LS_64(info->chunk_size, I40IWQPSQ_LPBLSIZE) |
- LS_64(info->page_size, I40IWQPSQ_HPAGESIZE) |
+ LS_64(page_size, I40IWQPSQ_HPAGESIZE) |
LS_64(info->access_rights, I40IWQPSQ_STAGRIGHTS) |
LS_64(info->addr_type, I40IWQPSQ_VABASEDTO) |
LS_64(info->read_fence, I40IWQPSQ_READFENCE) |
@@ -3959,7 +4111,7 @@ enum i40iw_status_code i40iw_process_cqp_cmd(struct i40iw_sc_dev *dev,
struct cqp_commands_info *pcmdinfo)
{
enum i40iw_status_code status = 0;
- unsigned long flags;
+ unsigned long flags;
spin_lock_irqsave(&dev->cqp_lock, flags);
if (list_empty(&dev->cqp_cmd_head) && !i40iw_ring_full(dev->cqp))
@@ -3978,7 +4130,7 @@ enum i40iw_status_code i40iw_process_bh(struct i40iw_sc_dev *dev)
{
enum i40iw_status_code status = 0;
struct cqp_commands_info *pcmdinfo;
- unsigned long flags;
+ unsigned long flags;
spin_lock_irqsave(&dev->cqp_lock, flags);
while (!list_empty(&dev->cqp_cmd_head) && !i40iw_ring_full(dev->cqp)) {
@@ -4055,7 +4207,6 @@ static int i40iw_bld_terminate_hdr(struct i40iw_sc_qp *qp,
u16 ddp_seg_len;
int copy_len = 0;
u8 is_tagged = 0;
- enum i40iw_flush_opcode flush_code = FLUSH_INVALID;
u32 opcode;
struct i40iw_terminate_hdr *termhdr;
@@ -4228,9 +4379,6 @@ static int i40iw_bld_terminate_hdr(struct i40iw_sc_qp *qp,
if (copy_len)
memcpy(termhdr + 1, pkt, copy_len);
- if (flush_code && !info->in_rdrsp_wr)
- qp->sq_flush = (info->sq) ? true : false;
-
return sizeof(struct i40iw_terminate_hdr) + copy_len;
}
@@ -4321,286 +4469,370 @@ void i40iw_terminate_received(struct i40iw_sc_qp *qp, struct i40iw_aeqe_info *in
}
/**
- * i40iw_hw_stat_init - Initiliaze HW stats table
- * @devstat: pestat struct
+ * i40iw_sc_vsi_init - Initialize virtual device
+ * @vsi: pointer to the vsi structure
+ * @info: parameters to initialize vsi
+ **/
+void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *info)
+{
+ int i;
+
+ vsi->dev = info->dev;
+ vsi->back_vsi = info->back_vsi;
+ vsi->mss = info->params->mss;
+ i40iw_fill_qos_list(info->params->qs_handle_list);
+
+ for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) {
+ vsi->qos[i].qs_handle =
+ info->params->qs_handle_list[i];
+ i40iw_debug(vsi->dev, I40IW_DEBUG_DCB, "qset[%d]: %d\n", i, vsi->qos[i].qs_handle);
+ spin_lock_init(&vsi->qos[i].lock);
+ INIT_LIST_HEAD(&vsi->qos[i].qplist);
+ }
+}
+
+/**
+ * i40iw_hw_stats_init - Initiliaze HW stats table
+ * @stats: pestat struct
* @fcn_idx: PCI fn id
- * @hw: PF i40iw_hw structure.
* @is_pf: Is it a PF?
*
- * Populate the HW stat table with register offset addr for each
- * stat. And start the perioidic stats timer.
+ * Populate the HW stats table with register offset addr for each
+ * stats. And start the perioidic stats timer.
*/
-static void i40iw_hw_stat_init(struct i40iw_dev_pestat *devstat,
- u8 fcn_idx,
- struct i40iw_hw *hw, bool is_pf)
+void i40iw_hw_stats_init(struct i40iw_vsi_pestat *stats, u8 fcn_idx, bool is_pf)
{
- u32 stat_reg_offset;
- u32 stat_index;
- struct i40iw_dev_hw_stat_offsets *stat_table =
- &devstat->hw_stat_offsets;
- struct i40iw_dev_hw_stats *last_rd_stats = &devstat->last_read_hw_stats;
-
- devstat->hw = hw;
+ u32 stats_reg_offset;
+ u32 stats_index;
+ struct i40iw_dev_hw_stats_offsets *stats_table =
+ &stats->hw_stats_offsets;
+ struct i40iw_dev_hw_stats *last_rd_stats = &stats->last_read_hw_stats;
if (is_pf) {
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP4RXDISCARD] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXDISCARD] =
I40E_GLPES_PFIP4RXDISCARD(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP4RXTRUNC] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXTRUNC] =
I40E_GLPES_PFIP4RXTRUNC(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP4TXNOROUTE] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4TXNOROUTE] =
I40E_GLPES_PFIP4TXNOROUTE(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP6RXDISCARD] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXDISCARD] =
I40E_GLPES_PFIP6RXDISCARD(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP6RXTRUNC] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXTRUNC] =
I40E_GLPES_PFIP6RXTRUNC(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP6TXNOROUTE] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6TXNOROUTE] =
I40E_GLPES_PFIP6TXNOROUTE(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_TCPRTXSEG] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRTXSEG] =
I40E_GLPES_PFTCPRTXSEG(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_TCPRXOPTERR] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXOPTERR] =
I40E_GLPES_PFTCPRXOPTERR(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_TCPRXPROTOERR] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXPROTOERR] =
I40E_GLPES_PFTCPRXPROTOERR(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXOCTS] =
I40E_GLPES_PFIP4RXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXPKTS] =
I40E_GLPES_PFIP4RXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXFRAGS] =
I40E_GLPES_PFIP4RXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXMCPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXMCPKTS] =
I40E_GLPES_PFIP4RXMCPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXOCTS] =
I40E_GLPES_PFIP4TXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXPKTS] =
I40E_GLPES_PFIP4TXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXFRAGS] =
I40E_GLPES_PFIP4TXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXMCPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXMCPKTS] =
I40E_GLPES_PFIP4TXMCPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXOCTS] =
I40E_GLPES_PFIP6RXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXPKTS] =
I40E_GLPES_PFIP6RXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXFRAGS] =
I40E_GLPES_PFIP6RXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXMCPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXMCPKTS] =
I40E_GLPES_PFIP6RXMCPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXOCTS] =
I40E_GLPES_PFIP6TXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
I40E_GLPES_PFIP6TXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
I40E_GLPES_PFIP6TXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXFRAGS] =
I40E_GLPES_PFIP6TXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_TCPRXSEGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPRXSEGS] =
I40E_GLPES_PFTCPRXSEGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_TCPTXSEG] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPTXSEG] =
I40E_GLPES_PFTCPTXSEGLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMARXRDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXRDS] =
I40E_GLPES_PFRDMARXRDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMARXSNDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXSNDS] =
I40E_GLPES_PFRDMARXSNDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMARXWRS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXWRS] =
I40E_GLPES_PFRDMARXWRSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMATXRDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXRDS] =
I40E_GLPES_PFRDMATXRDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMATXSNDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXSNDS] =
I40E_GLPES_PFRDMATXSNDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMATXWRS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXWRS] =
I40E_GLPES_PFRDMATXWRSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMAVBND] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVBND] =
I40E_GLPES_PFRDMAVBNDLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMAVINV] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVINV] =
I40E_GLPES_PFRDMAVINVLO(fcn_idx);
} else {
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP4RXDISCARD] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXDISCARD] =
I40E_GLPES_VFIP4RXDISCARD(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP4RXTRUNC] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4RXTRUNC] =
I40E_GLPES_VFIP4RXTRUNC(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP4TXNOROUTE] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP4TXNOROUTE] =
I40E_GLPES_VFIP4TXNOROUTE(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP6RXDISCARD] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXDISCARD] =
I40E_GLPES_VFIP6RXDISCARD(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP6RXTRUNC] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6RXTRUNC] =
I40E_GLPES_VFIP6RXTRUNC(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_IP6TXNOROUTE] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_IP6TXNOROUTE] =
I40E_GLPES_VFIP6TXNOROUTE(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_TCPRTXSEG] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRTXSEG] =
I40E_GLPES_VFTCPRTXSEG(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_TCPRXOPTERR] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXOPTERR] =
I40E_GLPES_VFTCPRXOPTERR(fcn_idx);
- stat_table->stat_offset_32[I40IW_HW_STAT_INDEX_TCPRXPROTOERR] =
+ stats_table->stats_offset_32[I40IW_HW_STAT_INDEX_TCPRXPROTOERR] =
I40E_GLPES_VFTCPRXPROTOERR(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXOCTS] =
I40E_GLPES_VFIP4RXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXPKTS] =
I40E_GLPES_VFIP4RXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXFRAGS] =
I40E_GLPES_VFIP4RXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4RXMCPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4RXMCPKTS] =
I40E_GLPES_VFIP4RXMCPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXOCTS] =
I40E_GLPES_VFIP4TXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXPKTS] =
I40E_GLPES_VFIP4TXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXFRAGS] =
I40E_GLPES_VFIP4TXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP4TXMCPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP4TXMCPKTS] =
I40E_GLPES_VFIP4TXMCPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXOCTS] =
I40E_GLPES_VFIP6RXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXPKTS] =
I40E_GLPES_VFIP6RXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXFRAGS] =
I40E_GLPES_VFIP6RXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6RXMCPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6RXMCPKTS] =
I40E_GLPES_VFIP6RXMCPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXOCTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXOCTS] =
I40E_GLPES_VFIP6TXOCTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
I40E_GLPES_VFIP6TXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXPKTS] =
I40E_GLPES_VFIP6TXPKTSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_IP6TXFRAGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_IP6TXFRAGS] =
I40E_GLPES_VFIP6TXFRAGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_TCPRXSEGS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPRXSEGS] =
I40E_GLPES_VFTCPRXSEGSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_TCPTXSEG] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_TCPTXSEG] =
I40E_GLPES_VFTCPTXSEGLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMARXRDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXRDS] =
I40E_GLPES_VFRDMARXRDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMARXSNDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXSNDS] =
I40E_GLPES_VFRDMARXSNDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMARXWRS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMARXWRS] =
I40E_GLPES_VFRDMARXWRSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMATXRDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXRDS] =
I40E_GLPES_VFRDMATXRDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMATXSNDS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXSNDS] =
I40E_GLPES_VFRDMATXSNDSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMATXWRS] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMATXWRS] =
I40E_GLPES_VFRDMATXWRSLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMAVBND] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVBND] =
I40E_GLPES_VFRDMAVBNDLO(fcn_idx);
- stat_table->stat_offset_64[I40IW_HW_STAT_INDEX_RDMAVINV] =
+ stats_table->stats_offset_64[I40IW_HW_STAT_INDEX_RDMAVINV] =
I40E_GLPES_VFRDMAVINVLO(fcn_idx);
}
- for (stat_index = 0; stat_index < I40IW_HW_STAT_INDEX_MAX_64;
- stat_index++) {
- stat_reg_offset = stat_table->stat_offset_64[stat_index];
- last_rd_stats->stat_value_64[stat_index] =
- readq(devstat->hw->hw_addr + stat_reg_offset);
+ for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_64;
+ stats_index++) {
+ stats_reg_offset = stats_table->stats_offset_64[stats_index];
+ last_rd_stats->stats_value_64[stats_index] =
+ readq(stats->hw->hw_addr + stats_reg_offset);
}
- for (stat_index = 0; stat_index < I40IW_HW_STAT_INDEX_MAX_32;
- stat_index++) {
- stat_reg_offset = stat_table->stat_offset_32[stat_index];
- last_rd_stats->stat_value_32[stat_index] =
- i40iw_rd32(devstat->hw, stat_reg_offset);
+ for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_32;
+ stats_index++) {
+ stats_reg_offset = stats_table->stats_offset_32[stats_index];
+ last_rd_stats->stats_value_32[stats_index] =
+ i40iw_rd32(stats->hw, stats_reg_offset);
}
}
/**
- * i40iw_hw_stat_read_32 - Read 32-bit HW stat counters and accommodates for roll-overs.
- * @devstat: pestat struct
- * @index: index in HW stat table which contains offset reg-addr
- * @value: hw stat value
+ * i40iw_hw_stats_read_32 - Read 32-bit HW stats counters and accommodates for roll-overs.
+ * @stat: pestat struct
+ * @index: index in HW stats table which contains offset reg-addr
+ * @value: hw stats value
*/
-static void i40iw_hw_stat_read_32(struct i40iw_dev_pestat *devstat,
- enum i40iw_hw_stat_index_32b index,
- u64 *value)
+void i40iw_hw_stats_read_32(struct i40iw_vsi_pestat *stats,
+ enum i40iw_hw_stats_index_32b index,
+ u64 *value)
{
- struct i40iw_dev_hw_stat_offsets *stat_table =
- &devstat->hw_stat_offsets;
- struct i40iw_dev_hw_stats *last_rd_stats = &devstat->last_read_hw_stats;
- struct i40iw_dev_hw_stats *hw_stats = &devstat->hw_stats;
- u64 new_stat_value = 0;
- u32 stat_reg_offset = stat_table->stat_offset_32[index];
-
- new_stat_value = i40iw_rd32(devstat->hw, stat_reg_offset);
+ struct i40iw_dev_hw_stats_offsets *stats_table =
+ &stats->hw_stats_offsets;
+ struct i40iw_dev_hw_stats *last_rd_stats = &stats->last_read_hw_stats;
+ struct i40iw_dev_hw_stats *hw_stats = &stats->hw_stats;
+ u64 new_stats_value = 0;
+ u32 stats_reg_offset = stats_table->stats_offset_32[index];
+
+ new_stats_value = i40iw_rd32(stats->hw, stats_reg_offset);
/*roll-over case */
- if (new_stat_value < last_rd_stats->stat_value_32[index])
- hw_stats->stat_value_32[index] += new_stat_value;
+ if (new_stats_value < last_rd_stats->stats_value_32[index])
+ hw_stats->stats_value_32[index] += new_stats_value;
else
- hw_stats->stat_value_32[index] +=
- new_stat_value - last_rd_stats->stat_value_32[index];
- last_rd_stats->stat_value_32[index] = new_stat_value;
- *value = hw_stats->stat_value_32[index];
+ hw_stats->stats_value_32[index] +=
+ new_stats_value - last_rd_stats->stats_value_32[index];
+ last_rd_stats->stats_value_32[index] = new_stats_value;
+ *value = hw_stats->stats_value_32[index];
}
/**
- * i40iw_hw_stat_read_64 - Read HW stat counters (greater than 32-bit) and accommodates for roll-overs.
- * @devstat: pestat struct
- * @index: index in HW stat table which contains offset reg-addr
- * @value: hw stat value
+ * i40iw_hw_stats_read_64 - Read HW stats counters (greater than 32-bit) and accommodates for roll-overs.
+ * @stats: pestat struct
+ * @index: index in HW stats table which contains offset reg-addr
+ * @value: hw stats value
*/
-static void i40iw_hw_stat_read_64(struct i40iw_dev_pestat *devstat,
- enum i40iw_hw_stat_index_64b index,
- u64 *value)
+void i40iw_hw_stats_read_64(struct i40iw_vsi_pestat *stats,
+ enum i40iw_hw_stats_index_64b index,
+ u64 *value)
{
- struct i40iw_dev_hw_stat_offsets *stat_table =
- &devstat->hw_stat_offsets;
- struct i40iw_dev_hw_stats *last_rd_stats = &devstat->last_read_hw_stats;
- struct i40iw_dev_hw_stats *hw_stats = &devstat->hw_stats;
- u64 new_stat_value = 0;
- u32 stat_reg_offset = stat_table->stat_offset_64[index];
-
- new_stat_value = readq(devstat->hw->hw_addr + stat_reg_offset);
+ struct i40iw_dev_hw_stats_offsets *stats_table =
+ &stats->hw_stats_offsets;
+ struct i40iw_dev_hw_stats *last_rd_stats = &stats->last_read_hw_stats;
+ struct i40iw_dev_hw_stats *hw_stats = &stats->hw_stats;
+ u64 new_stats_value = 0;
+ u32 stats_reg_offset = stats_table->stats_offset_64[index];
+
+ new_stats_value = readq(stats->hw->hw_addr + stats_reg_offset);
/*roll-over case */
- if (new_stat_value < last_rd_stats->stat_value_64[index])
- hw_stats->stat_value_64[index] += new_stat_value;
+ if (new_stats_value < last_rd_stats->stats_value_64[index])
+ hw_stats->stats_value_64[index] += new_stats_value;
else
- hw_stats->stat_value_64[index] +=
- new_stat_value - last_rd_stats->stat_value_64[index];
- last_rd_stats->stat_value_64[index] = new_stat_value;
- *value = hw_stats->stat_value_64[index];
+ hw_stats->stats_value_64[index] +=
+ new_stats_value - last_rd_stats->stats_value_64[index];
+ last_rd_stats->stats_value_64[index] = new_stats_value;
+ *value = hw_stats->stats_value_64[index];
}
/**
- * i40iw_hw_stat_read_all - read all HW stat counters
- * @devstat: pestat struct
- * @stat_values: hw stats structure
+ * i40iw_hw_stats_read_all - read all HW stat counters
+ * @stats: pestat struct
+ * @stats_values: hw stats structure
*
* Read all the HW stat counters and populates hw_stats structure
- * of passed-in dev's pestat as well as copy created in stat_values.
+ * of passed-in vsi's pestat as well as copy created in stat_values.
*/
-static void i40iw_hw_stat_read_all(struct i40iw_dev_pestat *devstat,
- struct i40iw_dev_hw_stats *stat_values)
+void i40iw_hw_stats_read_all(struct i40iw_vsi_pestat *stats,
+ struct i40iw_dev_hw_stats *stats_values)
{
- u32 stat_index;
-
- for (stat_index = 0; stat_index < I40IW_HW_STAT_INDEX_MAX_32;
- stat_index++)
- i40iw_hw_stat_read_32(devstat, stat_index,
- &stat_values->stat_value_32[stat_index]);
- for (stat_index = 0; stat_index < I40IW_HW_STAT_INDEX_MAX_64;
- stat_index++)
- i40iw_hw_stat_read_64(devstat, stat_index,
- &stat_values->stat_value_64[stat_index]);
+ u32 stats_index;
+ unsigned long flags;
+
+ spin_lock_irqsave(&stats->lock, flags);
+
+ for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_32;
+ stats_index++)
+ i40iw_hw_stats_read_32(stats, stats_index,
+ &stats_values->stats_value_32[stats_index]);
+ for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_64;
+ stats_index++)
+ i40iw_hw_stats_read_64(stats, stats_index,
+ &stats_values->stats_value_64[stats_index]);
+ spin_unlock_irqrestore(&stats->lock, flags);
}
/**
- * i40iw_hw_stat_refresh_all - Update all HW stat structs
- * @devstat: pestat struct
- * @stat_values: hw stats structure
+ * i40iw_hw_stats_refresh_all - Update all HW stats structs
+ * @stats: pestat struct
*
- * Read all the HW stat counters to refresh values in hw_stats structure
+ * Read all the HW stats counters to refresh values in hw_stats structure
* of passed-in dev's pestat
*/
-static void i40iw_hw_stat_refresh_all(struct i40iw_dev_pestat *devstat)
+void i40iw_hw_stats_refresh_all(struct i40iw_vsi_pestat *stats)
+{
+ u64 stats_value;
+ u32 stats_index;
+ unsigned long flags;
+
+ spin_lock_irqsave(&stats->lock, flags);
+
+ for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_32;
+ stats_index++)
+ i40iw_hw_stats_read_32(stats, stats_index, &stats_value);
+ for (stats_index = 0; stats_index < I40IW_HW_STAT_INDEX_MAX_64;
+ stats_index++)
+ i40iw_hw_stats_read_64(stats, stats_index, &stats_value);
+ spin_unlock_irqrestore(&stats->lock, flags);
+}
+
+/**
+ * i40iw_get_fcn_id - Return the function id
+ * @dev: pointer to the device
+ */
+static u8 i40iw_get_fcn_id(struct i40iw_sc_dev *dev)
+{
+ u8 fcn_id = I40IW_INVALID_FCN_ID;
+ u8 i;
+
+ for (i = I40IW_FIRST_NON_PF_STAT; i < I40IW_MAX_STATS_COUNT; i++)
+ if (!dev->fcn_id_array[i]) {
+ fcn_id = i;
+ dev->fcn_id_array[i] = true;
+ break;
+ }
+ return fcn_id;
+}
+
+/**
+ * i40iw_vsi_stats_init - Initialize the vsi statistics
+ * @vsi: pointer to the vsi structure
+ * @info: The info structure used for initialization
+ */
+enum i40iw_status_code i40iw_vsi_stats_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_stats_info *info)
{
- u64 stat_value;
- u32 stat_index;
-
- for (stat_index = 0; stat_index < I40IW_HW_STAT_INDEX_MAX_32;
- stat_index++)
- i40iw_hw_stat_read_32(devstat, stat_index, &stat_value);
- for (stat_index = 0; stat_index < I40IW_HW_STAT_INDEX_MAX_64;
- stat_index++)
- i40iw_hw_stat_read_64(devstat, stat_index, &stat_value);
+ u8 fcn_id = info->fcn_id;
+
+ if (info->alloc_fcn_id)
+ fcn_id = i40iw_get_fcn_id(vsi->dev);
+
+ if (fcn_id == I40IW_INVALID_FCN_ID)
+ return I40IW_ERR_NOT_READY;
+
+ vsi->pestat = info->pestat;
+ vsi->pestat->hw = vsi->dev->hw;
+
+ if (info->stats_initialize) {
+ i40iw_hw_stats_init(vsi->pestat, fcn_id, true);
+ spin_lock_init(&vsi->pestat->lock);
+ i40iw_hw_stats_start_timer(vsi);
+ }
+ vsi->stats_fcn_id_alloc = info->alloc_fcn_id;
+ vsi->fcn_id = fcn_id;
+ return I40IW_SUCCESS;
+}
+
+/**
+ * i40iw_vsi_stats_free - Free the vsi stats
+ * @vsi: pointer to the vsi structure
+ */
+void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi)
+{
+ u8 fcn_id = vsi->fcn_id;
+
+ if ((vsi->stats_fcn_id_alloc) && (fcn_id != I40IW_INVALID_FCN_ID))
+ vsi->dev->fcn_id_array[fcn_id] = false;
+ i40iw_hw_stats_stop_timer(vsi);
}
static struct i40iw_cqp_ops iw_cqp_ops = {
@@ -4711,24 +4943,6 @@ static struct i40iw_hmc_ops iw_hmc_ops = {
NULL
};
-static const struct i40iw_device_pestat_ops iw_device_pestat_ops = {
- i40iw_hw_stat_init,
- i40iw_hw_stat_read_32,
- i40iw_hw_stat_read_64,
- i40iw_hw_stat_read_all,
- i40iw_hw_stat_refresh_all
-};
-
-/**
- * i40iw_device_init_pestat - Initialize the pestat structure
- * @dev: pestat struct
- */
-enum i40iw_status_code i40iw_device_init_pestat(struct i40iw_dev_pestat *devstat)
-{
- devstat->ops = iw_device_pestat_ops;
- return 0;
-}
-
/**
* i40iw_device_init - Initialize IWARP device
* @dev: IWARP device pointer
@@ -4750,14 +4964,7 @@ enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev,
dev->debug_mask = info->debug_mask;
- ret_code = i40iw_device_init_pestat(&dev->dev_pestat);
- if (ret_code) {
- i40iw_debug(dev, I40IW_DEBUG_DEV,
- "%s: i40iw_device_init_pestat failed\n", __func__);
- return ret_code;
- }
dev->hmc_fn_id = info->hmc_fn_id;
- dev->qs_handle = info->qs_handle;
dev->exception_lan_queue = info->exception_lan_queue;
dev->is_pf = info->is_pf;
@@ -4770,15 +4977,10 @@ enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev,
dev->hw = info->hw;
dev->hw->hw_addr = info->bar0;
- val = i40iw_rd32(dev->hw, I40E_GLPCI_DREVID);
- dev->hw_rev = (u8)RS_32(val, I40E_GLPCI_DREVID_DEFAULT_REVID);
-
if (dev->is_pf) {
- dev->dev_pestat.ops.iw_hw_stat_init(&dev->dev_pestat,
- dev->hmc_fn_id, dev->hw, true);
- spin_lock_init(&dev->dev_pestat.stats_lock);
- /*start the periodic stats_timer */
- i40iw_hw_stats_start_timer(dev);
+ val = i40iw_rd32(dev->hw, I40E_GLPCI_DREVID);
+ dev->hw_rev = (u8)RS_32(val, I40E_GLPCI_DREVID_DEFAULT_REVID);
+
val = i40iw_rd32(dev->hw, I40E_GLPCI_LBARCTRL);
db_size = (u8)RS_32(val, I40E_GLPCI_LBARCTRL_PE_DB_SIZE);
if ((db_size != I40IW_PE_DB_SIZE_4M) &&
diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h
index 2fac1db0e0a0..a39ac12b6a7e 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_d.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_d.h
@@ -35,6 +35,8 @@
#ifndef I40IW_D_H
#define I40IW_D_H
+#define I40IW_FIRST_USER_QP_ID 2
+
#define I40IW_DB_ADDR_OFFSET (4 * 1024 * 1024 - 64 * 1024)
#define I40IW_VF_DB_ADDR_OFFSET (64 * 1024)
@@ -67,6 +69,9 @@
#define I40IW_STAG_TYPE_NONSHARED 1
#define I40IW_MAX_USER_PRIORITY 8
+#define I40IW_MAX_STATS_COUNT 16
+#define I40IW_FIRST_NON_PF_STAT 4
+
#define LS_64_1(val, bits) ((u64)(uintptr_t)val << bits)
#define RS_64_1(val, bits) ((u64)(uintptr_t)val >> bits)
@@ -74,6 +79,8 @@
#define RS_32_1(val, bits) (u32)(val >> bits)
#define I40E_HI_DWORD(x) ((u32)((((x) >> 16) >> 16) & 0xFFFFFFFF))
+#define QS_HANDLE_UNKNOWN 0xffff
+
#define LS_64(val, field) (((u64)val << field ## _SHIFT) & (field ## _MASK))
#define RS_64(val, field) ((u64)(val & field ## _MASK) >> field ## _SHIFT)
@@ -1199,8 +1206,11 @@
#define I40IWQPC_RXCQNUM_SHIFT 32
#define I40IWQPC_RXCQNUM_MASK (0x1ffffULL << I40IWQPC_RXCQNUM_SHIFT)
-#define I40IWQPC_Q2ADDR_SHIFT I40IW_CQPHC_QPCTX_SHIFT
-#define I40IWQPC_Q2ADDR_MASK I40IW_CQPHC_QPCTX_MASK
+#define I40IWQPC_STAT_INDEX_SHIFT 0
+#define I40IWQPC_STAT_INDEX_MASK (0x1fULL << I40IWQPC_STAT_INDEX_SHIFT)
+
+#define I40IWQPC_Q2ADDR_SHIFT 0
+#define I40IWQPC_Q2ADDR_MASK (0xffffffffffffff00ULL << I40IWQPC_Q2ADDR_SHIFT)
#define I40IWQPC_LASTBYTESENT_SHIFT 0
#define I40IWQPC_LASTBYTESENT_MASK (0xffUL << I40IWQPC_LASTBYTESENT_SHIFT)
@@ -1232,11 +1242,8 @@
#define I40IWQPC_PRIVEN_SHIFT 25
#define I40IWQPC_PRIVEN_MASK (1UL << I40IWQPC_PRIVEN_SHIFT)
-#define I40IWQPC_LSMMPRESENT_SHIFT 26
-#define I40IWQPC_LSMMPRESENT_MASK (1UL << I40IWQPC_LSMMPRESENT_SHIFT)
-
-#define I40IWQPC_ADJUSTFORLSMM_SHIFT 27
-#define I40IWQPC_ADJUSTFORLSMM_MASK (1UL << I40IWQPC_ADJUSTFORLSMM_SHIFT)
+#define I40IWQPC_USESTATSINSTANCE_SHIFT 26
+#define I40IWQPC_USESTATSINSTANCE_MASK (1UL << I40IWQPC_USESTATSINSTANCE_SHIFT)
#define I40IWQPC_IWARPMODE_SHIFT 28
#define I40IWQPC_IWARPMODE_MASK (1UL << I40IWQPC_IWARPMODE_SHIFT)
@@ -1713,6 +1720,8 @@ enum i40iw_alignment {
#define OP_MANAGE_VF_PBLE_BP 28
#define OP_QUERY_FPM_VALUES 29
#define OP_COMMIT_FPM_VALUES 30
-#define OP_SIZE_CQP_STAT_ARRAY 31
+#define OP_REQUESTED_COMMANDS 31
+#define OP_COMPLETED_COMMANDS 32
+#define OP_SIZE_CQP_STAT_ARRAY 33
#endif
diff --git a/drivers/infiniband/hw/i40iw/i40iw_hw.c b/drivers/infiniband/hw/i40iw/i40iw_hw.c
index 0c92a40b3e86..476867a3f584 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_hw.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_hw.c
@@ -62,7 +62,7 @@ u32 i40iw_initialize_hw_resources(struct i40iw_device *iwdev)
max_mr = iwdev->sc_dev.hmc_info->hmc_obj[I40IW_HMC_IW_MR].cnt;
arp_table_size = iwdev->sc_dev.hmc_info->hmc_obj[I40IW_HMC_IW_ARP].cnt;
iwdev->max_cqe = 0xFFFFF;
- num_pds = max_qp * 4;
+ num_pds = I40IW_MAX_PDS;
resources_size = sizeof(struct i40iw_arp_entry) * arp_table_size;
resources_size += sizeof(unsigned long) * BITS_TO_LONGS(max_qp);
resources_size += sizeof(unsigned long) * BITS_TO_LONGS(max_mr);
@@ -308,7 +308,9 @@ void i40iw_process_aeq(struct i40iw_device *iwdev)
iwqp = iwdev->qp_table[info->qp_cq_id];
if (!iwqp) {
spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
- i40iw_pr_err("qp_id %d is already freed\n", info->qp_cq_id);
+ i40iw_debug(dev, I40IW_DEBUG_AEQ,
+ "%s qp_id %d is already freed\n",
+ __func__, info->qp_cq_id);
continue;
}
i40iw_add_ref(&iwqp->ibqp);
@@ -359,6 +361,9 @@ void i40iw_process_aeq(struct i40iw_device *iwdev)
continue;
i40iw_cm_disconn(iwqp);
break;
+ case I40IW_AE_QP_SUSPEND_COMPLETE:
+ i40iw_qp_suspend_resume(dev, &iwqp->sc_qp, false);
+ break;
case I40IW_AE_TERMINATE_SENT:
i40iw_terminate_send_fin(qp);
break;
@@ -404,19 +409,18 @@ void i40iw_process_aeq(struct i40iw_device *iwdev)
case I40IW_AE_LCE_CQ_CATASTROPHIC:
case I40IW_AE_UDA_XMIT_DGRAM_TOO_LONG:
case I40IW_AE_UDA_XMIT_IPADDR_MISMATCH:
- case I40IW_AE_QP_SUSPEND_COMPLETE:
ctx_info->err_rq_idx_valid = false;
default:
- if (!info->sq && ctx_info->err_rq_idx_valid) {
- ctx_info->err_rq_idx = info->wqe_idx;
- ctx_info->tcp_info_valid = false;
- ctx_info->iwarp_info_valid = false;
- ret = dev->iw_priv_qp_ops->qp_setctx(&iwqp->sc_qp,
- iwqp->host_ctx.va,
- ctx_info);
- }
- i40iw_terminate_connection(qp, info);
- break;
+ if (!info->sq && ctx_info->err_rq_idx_valid) {
+ ctx_info->err_rq_idx = info->wqe_idx;
+ ctx_info->tcp_info_valid = false;
+ ctx_info->iwarp_info_valid = false;
+ ret = dev->iw_priv_qp_ops->qp_setctx(&iwqp->sc_qp,
+ iwqp->host_ctx.va,
+ ctx_info);
+ }
+ i40iw_terminate_connection(qp, info);
+ break;
}
if (info->qp)
i40iw_rem_ref(&iwqp->ibqp);
@@ -538,6 +542,7 @@ enum i40iw_status_code i40iw_manage_qhash(struct i40iw_device *iwdev,
{
struct i40iw_qhash_table_info *info;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
+ struct i40iw_sc_vsi *vsi = &iwdev->vsi;
enum i40iw_status_code status;
struct i40iw_cqp *iwcqp = &iwdev->cqp;
struct i40iw_cqp_request *cqp_request;
@@ -550,6 +555,7 @@ enum i40iw_status_code i40iw_manage_qhash(struct i40iw_device *iwdev,
info = &cqp_info->in.u.manage_qhash_table_entry.info;
memset(info, 0, sizeof(*info));
+ info->vsi = &iwdev->vsi;
info->manage = mtype;
info->entry_type = etype;
if (cminfo->vlan_id != 0xFFFF) {
@@ -560,8 +566,9 @@ enum i40iw_status_code i40iw_manage_qhash(struct i40iw_device *iwdev,
}
info->ipv4_valid = cminfo->ipv4;
+ info->user_pri = cminfo->user_pri;
ether_addr_copy(info->mac_addr, iwdev->netdev->dev_addr);
- info->qp_num = cpu_to_le32(dev->ilq->qp_id);
+ info->qp_num = cpu_to_le32(vsi->ilq->qp_id);
info->dest_port = cpu_to_le16(cminfo->loc_port);
info->dest_ip[0] = cpu_to_le32(cminfo->loc_addr[0]);
info->dest_ip[1] = cpu_to_le32(cminfo->loc_addr[1]);
@@ -617,6 +624,7 @@ enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
struct i40iw_qp_flush_info *hw_info;
struct i40iw_cqp_request *cqp_request;
struct cqp_commands_info *cqp_info;
+ struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp;
cqp_request = i40iw_get_cqp_request(&iwdev->cqp, wait);
if (!cqp_request)
@@ -631,9 +639,30 @@ enum i40iw_status_code i40iw_hw_flush_wqes(struct i40iw_device *iwdev,
cqp_info->in.u.qp_flush_wqes.qp = qp;
cqp_info->in.u.qp_flush_wqes.scratch = (uintptr_t)cqp_request;
status = i40iw_handle_cqp_op(iwdev, cqp_request);
- if (status)
+ if (status) {
i40iw_pr_err("CQP-OP Flush WQE's fail");
- return status;
+ complete(&iwqp->sq_drained);
+ complete(&iwqp->rq_drained);
+ return status;
+ }
+ if (!cqp_request->compl_info.maj_err_code) {
+ switch (cqp_request->compl_info.min_err_code) {
+ case I40IW_CQP_COMPL_RQ_WQE_FLUSHED:
+ complete(&iwqp->sq_drained);
+ break;
+ case I40IW_CQP_COMPL_SQ_WQE_FLUSHED:
+ complete(&iwqp->rq_drained);
+ break;
+ case I40IW_CQP_COMPL_RQ_SQ_WQE_FLUSHED:
+ break;
+ default:
+ complete(&iwqp->sq_drained);
+ complete(&iwqp->rq_drained);
+ break;
+ }
+ }
+
+ return 0;
}
/**
diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c
index ac2f3cd9478c..2728af3103ce 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_main.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_main.c
@@ -237,14 +237,11 @@ static irqreturn_t i40iw_irq_handler(int irq, void *data)
*/
static void i40iw_destroy_cqp(struct i40iw_device *iwdev, bool free_hwcqp)
{
- enum i40iw_status_code status = 0;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
struct i40iw_cqp *cqp = &iwdev->cqp;
- if (free_hwcqp && dev->cqp_ops->cqp_destroy)
- status = dev->cqp_ops->cqp_destroy(dev->cqp);
- if (status)
- i40iw_pr_err("destroy cqp failed");
+ if (free_hwcqp)
+ dev->cqp_ops->cqp_destroy(dev->cqp);
i40iw_free_dma_mem(dev->hw, &cqp->sq);
kfree(cqp->scratch_array);
@@ -270,6 +267,7 @@ static void i40iw_disable_irq(struct i40iw_sc_dev *dev,
i40iw_wr32(dev->hw, I40E_PFINT_DYN_CTLN(msix_vec->idx - 1), 0);
else
i40iw_wr32(dev->hw, I40E_VFINT_DYN_CTLN1(msix_vec->idx - 1), 0);
+ irq_set_affinity_hint(msix_vec->irq, NULL);
free_irq(msix_vec->irq, dev_id);
}
@@ -603,7 +601,7 @@ static enum i40iw_status_code i40iw_create_cqp(struct i40iw_device *iwdev)
i40iw_pr_err("cqp init status %d\n", status);
goto exit;
}
- status = dev->cqp_ops->cqp_create(dev->cqp, true, &maj_err, &min_err);
+ status = dev->cqp_ops->cqp_create(dev->cqp, &maj_err, &min_err);
if (status) {
i40iw_pr_err("cqp create status %d maj_err %d min_err %d\n",
status, maj_err, min_err);
@@ -688,6 +686,7 @@ static enum i40iw_status_code i40iw_configure_ceq_vector(struct i40iw_device *iw
struct i40iw_msix_vector *msix_vec)
{
enum i40iw_status_code status;
+ cpumask_t mask;
if (iwdev->msix_shared && !ceq_id) {
tasklet_init(&iwdev->dpc_tasklet, i40iw_dpc, (unsigned long)iwdev);
@@ -697,12 +696,15 @@ static enum i40iw_status_code i40iw_configure_ceq_vector(struct i40iw_device *iw
status = request_irq(msix_vec->irq, i40iw_ceq_handler, 0, "CEQ", iwceq);
}
+ cpumask_clear(&mask);
+ cpumask_set_cpu(msix_vec->cpu_affinity, &mask);
+ irq_set_affinity_hint(msix_vec->irq, &mask);
+
if (status) {
i40iw_pr_err("ceq irq config fail\n");
return I40IW_ERR_CONFIG;
}
msix_vec->ceq_id = ceq_id;
- msix_vec->cpu_affinity = 0;
return 0;
}
@@ -930,6 +932,7 @@ static enum i40iw_status_code i40iw_initialize_ilq(struct i40iw_device *iwdev)
struct i40iw_puda_rsrc_info info;
enum i40iw_status_code status;
+ memset(&info, 0, sizeof(info));
info.type = I40IW_PUDA_RSRC_TYPE_ILQ;
info.cq_id = 1;
info.qp_id = 0;
@@ -939,10 +942,9 @@ static enum i40iw_status_code i40iw_initialize_ilq(struct i40iw_device *iwdev)
info.rq_size = 8192;
info.buf_size = 1024;
info.tx_buf_cnt = 16384;
- info.mss = iwdev->mss;
info.receive = i40iw_receive_ilq;
info.xmit_complete = i40iw_free_sqbuf;
- status = i40iw_puda_create_rsrc(&iwdev->sc_dev, &info);
+ status = i40iw_puda_create_rsrc(&iwdev->vsi, &info);
if (status)
i40iw_pr_err("ilq create fail\n");
return status;
@@ -959,6 +961,7 @@ static enum i40iw_status_code i40iw_initialize_ieq(struct i40iw_device *iwdev)
struct i40iw_puda_rsrc_info info;
enum i40iw_status_code status;
+ memset(&info, 0, sizeof(info));
info.type = I40IW_PUDA_RSRC_TYPE_IEQ;
info.cq_id = 2;
info.qp_id = iwdev->sc_dev.exception_lan_queue;
@@ -967,9 +970,8 @@ static enum i40iw_status_code i40iw_initialize_ieq(struct i40iw_device *iwdev)
info.sq_size = 8192;
info.rq_size = 8192;
info.buf_size = 2048;
- info.mss = iwdev->mss;
info.tx_buf_cnt = 16384;
- status = i40iw_puda_create_rsrc(&iwdev->sc_dev, &info);
+ status = i40iw_puda_create_rsrc(&iwdev->vsi, &info);
if (status)
i40iw_pr_err("ieq create fail\n");
return status;
@@ -1159,7 +1161,7 @@ static void i40iw_add_ipv6_addr(struct i40iw_device *iwdev)
{
struct net_device *ip_dev;
struct inet6_dev *idev;
- struct inet6_ifaddr *ifp;
+ struct inet6_ifaddr *ifp, *tmp;
u32 local_ipaddr6[4];
rcu_read_lock();
@@ -1172,7 +1174,7 @@ static void i40iw_add_ipv6_addr(struct i40iw_device *iwdev)
i40iw_pr_err("ipv6 inet device not found\n");
break;
}
- list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) {
i40iw_pr_info("IP=%pI6, vlan_id=%d, MAC=%pM\n", &ifp->addr,
rdma_vlan_dev_vlan_id(ip_dev), ip_dev->dev_addr);
i40iw_copy_ip_ntohl(local_ipaddr6,
@@ -1294,17 +1296,23 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev,
enum i40iw_status_code status;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
struct i40iw_device_init_info info;
+ struct i40iw_vsi_init_info vsi_info;
struct i40iw_dma_mem mem;
+ struct i40iw_l2params l2params;
u32 size;
+ struct i40iw_vsi_stats_info stats_info;
+ u16 last_qset = I40IW_NO_QSET;
+ u16 qset;
+ u32 i;
+ memset(&l2params, 0, sizeof(l2params));
memset(&info, 0, sizeof(info));
size = sizeof(struct i40iw_hmc_pble_rsrc) + sizeof(struct i40iw_hmc_info) +
(sizeof(struct i40iw_hmc_obj_info) * I40IW_HMC_IW_MAX);
iwdev->hmc_info_mem = kzalloc(size, GFP_KERNEL);
- if (!iwdev->hmc_info_mem) {
- i40iw_pr_err("memory alloc fail\n");
+ if (!iwdev->hmc_info_mem)
return I40IW_ERR_NO_MEMORY;
- }
+
iwdev->pble_rsrc = (struct i40iw_hmc_pble_rsrc *)iwdev->hmc_info_mem;
dev->hmc_info = &iwdev->hw.hmc;
dev->hmc_info->hmc_obj = (struct i40iw_hmc_obj_info *)(iwdev->pble_rsrc + 1);
@@ -1325,7 +1333,17 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev,
info.bar0 = ldev->hw_addr;
info.hw = &iwdev->hw;
info.debug_mask = debug;
- info.qs_handle = ldev->params.qos.prio_qos[0].qs_handle;
+ l2params.mss =
+ (ldev->params.mtu) ? ldev->params.mtu - I40IW_MTU_TO_MSS : I40IW_DEFAULT_MSS;
+ for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++) {
+ qset = ldev->params.qos.prio_qos[i].qs_handle;
+ l2params.qs_handle_list[i] = qset;
+ if (last_qset == I40IW_NO_QSET)
+ last_qset = qset;
+ else if ((qset != last_qset) && (qset != I40IW_NO_QSET))
+ iwdev->dcb = true;
+ }
+ i40iw_pr_info("DCB is set/clear = %d\n", iwdev->dcb);
info.exception_lan_queue = 1;
info.vchnl_send = i40iw_virtchnl_send;
status = i40iw_device_init(&iwdev->sc_dev, &info);
@@ -1334,6 +1352,20 @@ exit:
kfree(iwdev->hmc_info_mem);
iwdev->hmc_info_mem = NULL;
}
+ memset(&vsi_info, 0, sizeof(vsi_info));
+ vsi_info.dev = &iwdev->sc_dev;
+ vsi_info.back_vsi = (void *)iwdev;
+ vsi_info.params = &l2params;
+ i40iw_sc_vsi_init(&iwdev->vsi, &vsi_info);
+
+ if (dev->is_pf) {
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.fcn_id = ldev->fid;
+ stats_info.pestat = kzalloc(sizeof(*stats_info.pestat), GFP_KERNEL);
+ stats_info.stats_initialize = true;
+ if (stats_info.pestat)
+ i40iw_vsi_stats_init(&iwdev->vsi, &stats_info);
+ }
return status;
}
@@ -1384,6 +1416,7 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev,
for (i = 0, ceq_idx = 0; i < iwdev->msix_count; i++, iw_qvinfo++) {
iwdev->iw_msixtbl[i].idx = ldev->msix_entries[i].entry;
iwdev->iw_msixtbl[i].irq = ldev->msix_entries[i].vector;
+ iwdev->iw_msixtbl[i].cpu_affinity = ceq_idx;
if (i == 0) {
iw_qvinfo->aeq_idx = 0;
if (iwdev->msix_shared)
@@ -1404,18 +1437,19 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev,
* i40iw_deinit_device - clean up the device resources
* @iwdev: iwarp device
* @reset: true if called before reset
- * @del_hdl: true if delete hdl entry
*
* Destroy the ib device interface, remove the mac ip entry and ipv4/ipv6 addresses,
* destroy the device queues and free the pble and the hmc objects
*/
-static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset, bool del_hdl)
+static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset)
{
struct i40e_info *ldev = iwdev->ldev;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
i40iw_pr_info("state = %d\n", iwdev->init_state);
+ if (iwdev->param_wq)
+ destroy_workqueue(iwdev->param_wq);
switch (iwdev->init_state) {
case RDMA_DEV_REGISTERED:
@@ -1441,10 +1475,10 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset, bool del
i40iw_destroy_aeq(iwdev, reset);
/* fallthrough */
case IEQ_CREATED:
- i40iw_puda_dele_resources(dev, I40IW_PUDA_RSRC_TYPE_IEQ, reset);
+ i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_IEQ, reset);
/* fallthrough */
case ILQ_CREATED:
- i40iw_puda_dele_resources(dev, I40IW_PUDA_RSRC_TYPE_ILQ, reset);
+ i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_ILQ, reset);
/* fallthrough */
case CCQ_CREATED:
i40iw_destroy_ccq(iwdev, reset);
@@ -1456,13 +1490,14 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset, bool del
i40iw_del_hmc_objects(dev, dev->hmc_info, true, reset);
/* fallthrough */
case CQP_CREATED:
- i40iw_destroy_cqp(iwdev, !reset);
+ i40iw_destroy_cqp(iwdev, true);
/* fallthrough */
case INITIAL_STATE:
i40iw_cleanup_cm_core(&iwdev->cm_core);
- if (dev->is_pf)
- i40iw_hw_stats_del_timer(dev);
-
+ if (iwdev->vsi.pestat) {
+ i40iw_vsi_stats_free(&iwdev->vsi);
+ kfree(iwdev->vsi.pestat);
+ }
i40iw_del_init_mem(iwdev);
break;
case INVALID_STATE:
@@ -1472,8 +1507,7 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset, bool del
break;
}
- if (del_hdl)
- i40iw_del_handler(i40iw_find_i40e_handler(ldev));
+ i40iw_del_handler(i40iw_find_i40e_handler(ldev));
kfree(iwdev->hdl);
}
@@ -1508,7 +1542,6 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl,
iwdev->max_enabled_vfs = iwdev->max_rdma_vfs;
iwdev->netdev = ldev->netdev;
hdl->client = client;
- iwdev->mss = (!ldev->params.mtu) ? I40IW_DEFAULT_MSS : ldev->params.mtu - I40IW_MTU_TO_MSS;
if (!ldev->ftype)
iwdev->db_start = pci_resource_start(ldev->pcidev, 0) + I40IW_DB_ADDR_OFFSET;
else
@@ -1528,6 +1561,7 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl,
init_waitqueue_head(&iwdev->vchnl_waitq);
init_waitqueue_head(&dev->vf_reqs);
+ init_waitqueue_head(&iwdev->close_wq);
status = i40iw_initialize_dev(iwdev, ldev);
exit:
@@ -1540,6 +1574,20 @@ exit:
}
/**
+ * i40iw_get_used_rsrc - determine resources used internally
+ * @iwdev: iwarp device
+ *
+ * Called after internal allocations
+ */
+static void i40iw_get_used_rsrc(struct i40iw_device *iwdev)
+{
+ iwdev->used_pds = find_next_zero_bit(iwdev->allocated_pds, iwdev->max_pd, 0);
+ iwdev->used_qps = find_next_zero_bit(iwdev->allocated_qps, iwdev->max_qp, 0);
+ iwdev->used_cqs = find_next_zero_bit(iwdev->allocated_cqs, iwdev->max_cq, 0);
+ iwdev->used_mrs = find_next_zero_bit(iwdev->allocated_mrs, iwdev->max_mr, 0);
+}
+
+/**
* i40iw_open - client interface operation open for iwarp/uda device
* @ldev: lan device information
* @client: iwarp client information, provided during registration
@@ -1611,6 +1659,7 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client)
status = i40iw_initialize_hw_resources(iwdev);
if (status)
break;
+ i40iw_get_used_rsrc(iwdev);
dev->ccq_ops->ccq_arm(dev->ccq);
status = i40iw_hmc_init_pble(&iwdev->sc_dev, iwdev->pble_rsrc);
if (status)
@@ -1630,35 +1679,73 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client)
iwdev->init_state = RDMA_DEV_REGISTERED;
iwdev->iw_status = 1;
i40iw_port_ibevent(iwdev);
+ iwdev->param_wq = alloc_ordered_workqueue("l2params", WQ_MEM_RECLAIM);
+ if(iwdev->param_wq == NULL)
+ break;
i40iw_pr_info("i40iw_open completed\n");
return 0;
} while (0);
i40iw_pr_err("status = %d last completion = %d\n", status, iwdev->init_state);
- i40iw_deinit_device(iwdev, false, false);
+ i40iw_deinit_device(iwdev, false);
return -ERESTART;
}
/**
- * i40iw_l2param_change : handle qs handles for qos and mss change
+ * i40iw_l2params_worker - worker for l2 params change
+ * @work: work pointer for l2 params
+ */
+static void i40iw_l2params_worker(struct work_struct *work)
+{
+ struct l2params_work *dwork =
+ container_of(work, struct l2params_work, work);
+ struct i40iw_device *iwdev = dwork->iwdev;
+
+ i40iw_change_l2params(&iwdev->vsi, &dwork->l2params);
+ atomic_dec(&iwdev->params_busy);
+ kfree(work);
+}
+
+/**
+ * i40iw_l2param_change - handle qs handles for qos and mss change
* @ldev: lan device information
* @client: client for paramater change
* @params: new parameters from L2
*/
-static void i40iw_l2param_change(struct i40e_info *ldev,
- struct i40e_client *client,
+static void i40iw_l2param_change(struct i40e_info *ldev, struct i40e_client *client,
struct i40e_params *params)
{
struct i40iw_handler *hdl;
+ struct i40iw_l2params *l2params;
+ struct l2params_work *work;
struct i40iw_device *iwdev;
+ int i;
hdl = i40iw_find_i40e_handler(ldev);
if (!hdl)
return;
iwdev = &hdl->device;
- if (params->mtu)
- iwdev->mss = params->mtu - I40IW_MTU_TO_MSS;
+
+ if (atomic_read(&iwdev->params_busy))
+ return;
+
+
+ work = kzalloc(sizeof(*work), GFP_ATOMIC);
+ if (!work)
+ return;
+
+ atomic_inc(&iwdev->params_busy);
+
+ work->iwdev = iwdev;
+ l2params = &work->l2params;
+ for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++)
+ l2params->qs_handle_list[i] = params->qos.prio_qos[i].qs_handle;
+
+ l2params->mss = (params->mtu) ? params->mtu - I40IW_MTU_TO_MSS : iwdev->vsi.mss;
+
+ INIT_WORK(&work->work, i40iw_l2params_worker);
+ queue_work(iwdev->param_wq, &work->work);
}
/**
@@ -1679,8 +1766,11 @@ static void i40iw_close(struct i40e_info *ldev, struct i40e_client *client, bool
return;
iwdev = &hdl->device;
+ iwdev->closing = true;
+
+ i40iw_cm_disconnect_all(iwdev);
destroy_workqueue(iwdev->virtchnl_wq);
- i40iw_deinit_device(iwdev, reset, true);
+ i40iw_deinit_device(iwdev, reset);
}
/**
@@ -1701,21 +1791,23 @@ static void i40iw_vf_reset(struct i40e_info *ldev, struct i40e_client *client, u
struct i40iw_vfdev *tmp_vfdev;
unsigned int i;
unsigned long flags;
+ struct i40iw_device *iwdev;
hdl = i40iw_find_i40e_handler(ldev);
if (!hdl)
return;
dev = &hdl->device.sc_dev;
+ iwdev = (struct i40iw_device *)dev->back_dev;
for (i = 0; i < I40IW_MAX_PE_ENABLED_VF_COUNT; i++) {
if (!dev->vf_dev[i] || (dev->vf_dev[i]->vf_id != vf_id))
continue;
/* free all resources allocated on behalf of vf */
tmp_vfdev = dev->vf_dev[i];
- spin_lock_irqsave(&dev->dev_pestat.stats_lock, flags);
+ spin_lock_irqsave(&iwdev->vsi.pestat->lock, flags);
dev->vf_dev[i] = NULL;
- spin_unlock_irqrestore(&dev->dev_pestat.stats_lock, flags);
+ spin_unlock_irqrestore(&iwdev->vsi.pestat->lock, flags);
i40iw_del_hmc_objects(dev, &tmp_vfdev->hmc_info, false, false);
/* remove vf hmc function */
memset(&hmc_fcn_info, 0, sizeof(hmc_fcn_info));
diff --git a/drivers/infiniband/hw/i40iw/i40iw_osdep.h b/drivers/infiniband/hw/i40iw/i40iw_osdep.h
index 80f422bf3967..aa66c1c63dfa 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_osdep.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_osdep.h
@@ -198,6 +198,8 @@ enum i40iw_status_code i40iw_cqp_manage_vf_pble_bp(struct i40iw_sc_dev *dev,
void i40iw_cqp_spawn_worker(struct i40iw_sc_dev *dev,
struct i40iw_virtchnl_work_info *work_info, u32 iw_vf_idx);
void *i40iw_remove_head(struct list_head *list);
+void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp, bool suspend);
+void i40iw_qp_mss_modify(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
void i40iw_term_modify_qp(struct i40iw_sc_qp *qp, u8 next_state, u8 term, u8 term_len);
void i40iw_terminate_done(struct i40iw_sc_qp *qp, int timeout_occurred);
@@ -207,9 +209,9 @@ void i40iw_terminate_del_timer(struct i40iw_sc_qp *qp);
enum i40iw_status_code i40iw_hw_manage_vf_pble_bp(struct i40iw_device *iwdev,
struct i40iw_manage_vf_pble_info *info,
bool wait);
-struct i40iw_dev_pestat;
-void i40iw_hw_stats_start_timer(struct i40iw_sc_dev *);
-void i40iw_hw_stats_del_timer(struct i40iw_sc_dev *);
+struct i40iw_sc_vsi;
+void i40iw_hw_stats_start_timer(struct i40iw_sc_vsi *vsi);
+void i40iw_hw_stats_stop_timer(struct i40iw_sc_vsi *vsi);
#define i40iw_mmiowb() mmiowb()
void i40iw_wr32(struct i40iw_hw *hw, u32 reg, u32 value);
u32 i40iw_rd32(struct i40iw_hw *hw, u32 reg);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_p.h b/drivers/infiniband/hw/i40iw/i40iw_p.h
index a0b8ca10d67e..28a92fee0822 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_p.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_p.h
@@ -47,8 +47,6 @@ void i40iw_debug_buf(struct i40iw_sc_dev *dev, enum i40iw_debug_flag mask,
enum i40iw_status_code i40iw_device_init(struct i40iw_sc_dev *dev,
struct i40iw_device_init_info *info);
-enum i40iw_status_code i40iw_device_init_pestat(struct i40iw_dev_pestat *);
-
void i40iw_sc_cqp_post_sq(struct i40iw_sc_cqp *cqp);
u64 *i40iw_sc_cqp_get_next_send_wqe(struct i40iw_sc_cqp *cqp, u64 scratch);
@@ -64,7 +62,24 @@ enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev,
enum i40iw_status_code i40iw_pf_init_vfhmc(struct i40iw_sc_dev *dev, u8 vf_hmc_fn_id,
u32 *vf_cnt_array);
-/* cqp misc functions */
+/* stats functions */
+void i40iw_hw_stats_refresh_all(struct i40iw_vsi_pestat *stats);
+void i40iw_hw_stats_read_all(struct i40iw_vsi_pestat *stats, struct i40iw_dev_hw_stats *stats_values);
+void i40iw_hw_stats_read_32(struct i40iw_vsi_pestat *stats,
+ enum i40iw_hw_stats_index_32b index,
+ u64 *value);
+void i40iw_hw_stats_read_64(struct i40iw_vsi_pestat *stats,
+ enum i40iw_hw_stats_index_64b index,
+ u64 *value);
+void i40iw_hw_stats_init(struct i40iw_vsi_pestat *stats, u8 index, bool is_pf);
+
+/* vsi misc functions */
+enum i40iw_status_code i40iw_vsi_stats_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_stats_info *info);
+void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi);
+void i40iw_sc_vsi_init(struct i40iw_sc_vsi *vsi, struct i40iw_vsi_init_info *info);
+
+void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2params);
+void i40iw_qp_add_qos(struct i40iw_sc_qp *qp);
void i40iw_terminate_send_fin(struct i40iw_sc_qp *qp);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_pble.c b/drivers/infiniband/hw/i40iw/i40iw_pble.c
index 85993dc44f6e..c87ba1617087 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_pble.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_pble.c
@@ -353,10 +353,6 @@ static enum i40iw_status_code add_pble_pool(struct i40iw_sc_dev *dev,
pages = (idx->rel_pd_idx) ? (I40IW_HMC_PD_CNT_IN_SD -
idx->rel_pd_idx) : I40IW_HMC_PD_CNT_IN_SD;
pages = min(pages, pble_rsrc->unallocated_pble >> PBLE_512_SHIFT);
- if (!pages) {
- ret_code = I40IW_ERR_NO_PBLCHUNKS_AVAILABLE;
- goto error;
- }
info.chunk = chunk;
info.hmc_info = hmc_info;
info.pages = pages;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c
index c62d354f7810..449ba8c81ce7 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c
@@ -42,12 +42,13 @@
#include "i40iw_p.h"
#include "i40iw_puda.h"
-static void i40iw_ieq_receive(struct i40iw_sc_dev *dev,
+static void i40iw_ieq_receive(struct i40iw_sc_vsi *vsi,
struct i40iw_puda_buf *buf);
-static void i40iw_ieq_tx_compl(struct i40iw_sc_dev *dev, void *sqwrid);
+static void i40iw_ieq_tx_compl(struct i40iw_sc_vsi *vsi, void *sqwrid);
static void i40iw_ilq_putback_rcvbuf(struct i40iw_sc_qp *qp, u32 wqe_idx);
static enum i40iw_status_code i40iw_puda_replenish_rq(struct i40iw_puda_rsrc
*rsrc, bool initial);
+static void i40iw_ieq_cleanup_qp(struct i40iw_puda_rsrc *ieq, struct i40iw_sc_qp *qp);
/**
* i40iw_puda_get_listbuf - get buffer from puda list
* @list: list to use for buffers (ILQ or IEQ)
@@ -292,7 +293,7 @@ enum i40iw_status_code i40iw_puda_poll_completion(struct i40iw_sc_dev *dev,
unsigned long flags;
if ((cq_type == I40IW_CQ_TYPE_ILQ) || (cq_type == I40IW_CQ_TYPE_IEQ)) {
- rsrc = (cq_type == I40IW_CQ_TYPE_ILQ) ? dev->ilq : dev->ieq;
+ rsrc = (cq_type == I40IW_CQ_TYPE_ILQ) ? cq->vsi->ilq : cq->vsi->ieq;
} else {
i40iw_debug(dev, I40IW_DEBUG_PUDA, "%s qp_type error\n", __func__);
return I40IW_ERR_BAD_PTR;
@@ -335,7 +336,7 @@ enum i40iw_status_code i40iw_puda_poll_completion(struct i40iw_sc_dev *dev,
rsrc->stats_pkt_rcvd++;
rsrc->compl_rxwqe_idx = info.wqe_idx;
i40iw_debug(dev, I40IW_DEBUG_PUDA, "%s RQ completion\n", __func__);
- rsrc->receive(rsrc->dev, buf);
+ rsrc->receive(rsrc->vsi, buf);
if (cq_type == I40IW_CQ_TYPE_ILQ)
i40iw_ilq_putback_rcvbuf(&rsrc->qp, info.wqe_idx);
else
@@ -345,12 +346,12 @@ enum i40iw_status_code i40iw_puda_poll_completion(struct i40iw_sc_dev *dev,
i40iw_debug(dev, I40IW_DEBUG_PUDA, "%s SQ completion\n", __func__);
sqwrid = (void *)(uintptr_t)qp->sq_wrtrk_array[info.wqe_idx].wrid;
I40IW_RING_SET_TAIL(qp->sq_ring, info.wqe_idx);
- rsrc->xmit_complete(rsrc->dev, sqwrid);
+ rsrc->xmit_complete(rsrc->vsi, sqwrid);
spin_lock_irqsave(&rsrc->bufpool_lock, flags);
rsrc->tx_wqe_avail_cnt++;
spin_unlock_irqrestore(&rsrc->bufpool_lock, flags);
- if (!list_empty(&dev->ilq->txpend))
- i40iw_puda_send_buf(dev->ilq, NULL);
+ if (!list_empty(&rsrc->vsi->ilq->txpend))
+ i40iw_puda_send_buf(rsrc->vsi->ilq, NULL);
}
done:
@@ -513,10 +514,8 @@ static void i40iw_puda_qp_setctx(struct i40iw_puda_rsrc *rsrc)
* i40iw_puda_qp_wqe - setup wqe for qp create
* @rsrc: resource for qp
*/
-static enum i40iw_status_code i40iw_puda_qp_wqe(struct i40iw_puda_rsrc *rsrc)
+static enum i40iw_status_code i40iw_puda_qp_wqe(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp)
{
- struct i40iw_sc_qp *qp = &rsrc->qp;
- struct i40iw_sc_dev *dev = rsrc->dev;
struct i40iw_sc_cqp *cqp;
u64 *wqe;
u64 header;
@@ -582,6 +581,7 @@ static enum i40iw_status_code i40iw_puda_qp_create(struct i40iw_puda_rsrc *rsrc)
qp->back_qp = (void *)rsrc;
qp->sq_pa = mem->pa;
qp->rq_pa = qp->sq_pa + sq_size;
+ qp->vsi = rsrc->vsi;
ukqp->sq_base = mem->va;
ukqp->rq_base = &ukqp->sq_base[rsrc->sq_size];
ukqp->shadow_area = ukqp->rq_base[rsrc->rq_size].elem;
@@ -608,15 +608,63 @@ static enum i40iw_status_code i40iw_puda_qp_create(struct i40iw_puda_rsrc *rsrc)
ukqp->wqe_alloc_reg = (u32 __iomem *)(i40iw_get_hw_addr(qp->pd->dev) +
I40E_VFPE_WQEALLOC1);
- qp->qs_handle = qp->dev->qs_handle;
+ qp->user_pri = 0;
+ i40iw_qp_add_qos(qp);
i40iw_puda_qp_setctx(rsrc);
- ret = i40iw_puda_qp_wqe(rsrc);
+ if (rsrc->ceq_valid)
+ ret = i40iw_cqp_qp_create_cmd(rsrc->dev, qp);
+ else
+ ret = i40iw_puda_qp_wqe(rsrc->dev, qp);
if (ret)
i40iw_free_dma_mem(rsrc->dev->hw, &rsrc->qpmem);
return ret;
}
/**
+ * i40iw_puda_cq_wqe - setup wqe for cq create
+ * @rsrc: resource for cq
+ */
+static enum i40iw_status_code i40iw_puda_cq_wqe(struct i40iw_sc_dev *dev, struct i40iw_sc_cq *cq)
+{
+ u64 *wqe;
+ struct i40iw_sc_cqp *cqp;
+ u64 header;
+ struct i40iw_ccq_cqe_info compl_info;
+ enum i40iw_status_code status = 0;
+
+ cqp = dev->cqp;
+ wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, 0);
+ if (!wqe)
+ return I40IW_ERR_RING_FULL;
+
+ set_64bit_val(wqe, 0, cq->cq_uk.cq_size);
+ set_64bit_val(wqe, 8, RS_64_1(cq, 1));
+ set_64bit_val(wqe, 16,
+ LS_64(cq->shadow_read_threshold,
+ I40IW_CQPSQ_CQ_SHADOW_READ_THRESHOLD));
+ set_64bit_val(wqe, 32, cq->cq_pa);
+
+ set_64bit_val(wqe, 40, cq->shadow_area_pa);
+
+ header = cq->cq_uk.cq_id |
+ LS_64(I40IW_CQP_OP_CREATE_CQ, I40IW_CQPSQ_OPCODE) |
+ LS_64(1, I40IW_CQPSQ_CQ_CHKOVERFLOW) |
+ LS_64(1, I40IW_CQPSQ_CQ_ENCEQEMASK) |
+ LS_64(1, I40IW_CQPSQ_CQ_CEQIDVALID) |
+ LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
+ set_64bit_val(wqe, 24, header);
+
+ i40iw_debug_buf(dev, I40IW_DEBUG_PUDA, "PUDA CQE",
+ wqe, I40IW_CQP_WQE_SIZE * 8);
+
+ i40iw_sc_cqp_post_sq(dev->cqp);
+ status = dev->cqp_ops->poll_for_cqp_op_done(dev->cqp,
+ I40IW_CQP_OP_CREATE_CQ,
+ &compl_info);
+ return status;
+}
+
+/**
* i40iw_puda_cq_create - create cq for resource
* @rsrc: resource for which cq to create
*/
@@ -624,18 +672,13 @@ static enum i40iw_status_code i40iw_puda_cq_create(struct i40iw_puda_rsrc *rsrc)
{
struct i40iw_sc_dev *dev = rsrc->dev;
struct i40iw_sc_cq *cq = &rsrc->cq;
- u64 *wqe;
- struct i40iw_sc_cqp *cqp;
- u64 header;
enum i40iw_status_code ret = 0;
u32 tsize, cqsize;
- u32 shadow_read_threshold = 128;
struct i40iw_dma_mem *mem;
- struct i40iw_ccq_cqe_info compl_info;
struct i40iw_cq_init_info info;
struct i40iw_cq_uk_init_info *init_info = &info.cq_uk_init_info;
- cq->back_cq = (void *)rsrc;
+ cq->vsi = rsrc->vsi;
cqsize = rsrc->cq_size * (sizeof(struct i40iw_cqe));
tsize = cqsize + sizeof(struct i40iw_cq_shadow_area);
ret = i40iw_allocate_dma_mem(dev->hw, &rsrc->cqmem, tsize,
@@ -656,43 +699,84 @@ static enum i40iw_status_code i40iw_puda_cq_create(struct i40iw_puda_rsrc *rsrc)
init_info->shadow_area = (u64 *)((u8 *)mem->va + cqsize);
init_info->cq_size = rsrc->cq_size;
init_info->cq_id = rsrc->cq_id;
+ info.ceqe_mask = true;
+ info.ceq_id_valid = true;
ret = dev->iw_priv_cq_ops->cq_init(cq, &info);
if (ret)
goto error;
- cqp = dev->cqp;
- wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, 0);
- if (!wqe) {
- ret = I40IW_ERR_RING_FULL;
- goto error;
- }
+ if (rsrc->ceq_valid)
+ ret = i40iw_cqp_cq_create_cmd(dev, cq);
+ else
+ ret = i40iw_puda_cq_wqe(dev, cq);
+error:
+ if (ret)
+ i40iw_free_dma_mem(dev->hw, &rsrc->cqmem);
+ return ret;
+}
- set_64bit_val(wqe, 0, rsrc->cq_size);
- set_64bit_val(wqe, 8, RS_64_1(cq, 1));
- set_64bit_val(wqe, 16, LS_64(shadow_read_threshold, I40IW_CQPSQ_CQ_SHADOW_READ_THRESHOLD));
- set_64bit_val(wqe, 32, cq->cq_pa);
+/**
+ * i40iw_puda_free_qp - free qp for resource
+ * @rsrc: resource for which qp to free
+ */
+static void i40iw_puda_free_qp(struct i40iw_puda_rsrc *rsrc)
+{
+ enum i40iw_status_code ret;
+ struct i40iw_ccq_cqe_info compl_info;
+ struct i40iw_sc_dev *dev = rsrc->dev;
- set_64bit_val(wqe, 40, cq->shadow_area_pa);
+ if (rsrc->ceq_valid) {
+ i40iw_cqp_qp_destroy_cmd(dev, &rsrc->qp);
+ return;
+ }
- header = rsrc->cq_id |
- LS_64(I40IW_CQP_OP_CREATE_CQ, I40IW_CQPSQ_OPCODE) |
- LS_64(1, I40IW_CQPSQ_CQ_CHKOVERFLOW) |
- LS_64(1, I40IW_CQPSQ_CQ_ENCEQEMASK) |
- LS_64(1, I40IW_CQPSQ_CQ_CEQIDVALID) |
- LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID);
- set_64bit_val(wqe, 24, header);
+ ret = dev->iw_priv_qp_ops->qp_destroy(&rsrc->qp,
+ 0, false, true, true);
+ if (ret)
+ i40iw_debug(dev, I40IW_DEBUG_PUDA,
+ "%s error puda qp destroy wqe\n",
+ __func__);
- i40iw_debug_buf(dev, I40IW_DEBUG_PUDA, "PUDA CQE",
- wqe, I40IW_CQP_WQE_SIZE * 8);
+ if (!ret) {
+ ret = dev->cqp_ops->poll_for_cqp_op_done(dev->cqp,
+ I40IW_CQP_OP_DESTROY_QP,
+ &compl_info);
+ if (ret)
+ i40iw_debug(dev, I40IW_DEBUG_PUDA,
+ "%s error puda qp destroy failed\n",
+ __func__);
+ }
+}
- i40iw_sc_cqp_post_sq(dev->cqp);
- ret = dev->cqp_ops->poll_for_cqp_op_done(dev->cqp,
- I40IW_CQP_OP_CREATE_CQ,
- &compl_info);
+/**
+ * i40iw_puda_free_cq - free cq for resource
+ * @rsrc: resource for which cq to free
+ */
+static void i40iw_puda_free_cq(struct i40iw_puda_rsrc *rsrc)
+{
+ enum i40iw_status_code ret;
+ struct i40iw_ccq_cqe_info compl_info;
+ struct i40iw_sc_dev *dev = rsrc->dev;
+
+ if (rsrc->ceq_valid) {
+ i40iw_cqp_cq_destroy_cmd(dev, &rsrc->cq);
+ return;
+ }
+ ret = dev->iw_priv_cq_ops->cq_destroy(&rsrc->cq, 0, true);
-error:
if (ret)
- i40iw_free_dma_mem(dev->hw, &rsrc->cqmem);
- return ret;
+ i40iw_debug(dev, I40IW_DEBUG_PUDA,
+ "%s error ieq cq destroy\n",
+ __func__);
+
+ if (!ret) {
+ ret = dev->cqp_ops->poll_for_cqp_op_done(dev->cqp,
+ I40IW_CQP_OP_DESTROY_CQ,
+ &compl_info);
+ if (ret)
+ i40iw_debug(dev, I40IW_DEBUG_PUDA,
+ "%s error ieq qp destroy done\n",
+ __func__);
+ }
}
/**
@@ -701,25 +785,24 @@ error:
* @type: type of resource to dele
* @reset: true if reset chip
*/
-void i40iw_puda_dele_resources(struct i40iw_sc_dev *dev,
+void i40iw_puda_dele_resources(struct i40iw_sc_vsi *vsi,
enum puda_resource_type type,
bool reset)
{
- struct i40iw_ccq_cqe_info compl_info;
+ struct i40iw_sc_dev *dev = vsi->dev;
struct i40iw_puda_rsrc *rsrc;
struct i40iw_puda_buf *buf = NULL;
struct i40iw_puda_buf *nextbuf = NULL;
struct i40iw_virt_mem *vmem;
- enum i40iw_status_code ret;
switch (type) {
case I40IW_PUDA_RSRC_TYPE_ILQ:
- rsrc = dev->ilq;
- vmem = &dev->ilq_mem;
+ rsrc = vsi->ilq;
+ vmem = &vsi->ilq_mem;
break;
case I40IW_PUDA_RSRC_TYPE_IEQ:
- rsrc = dev->ieq;
- vmem = &dev->ieq_mem;
+ rsrc = vsi->ieq;
+ vmem = &vsi->ieq_mem;
break;
default:
i40iw_debug(dev, I40IW_DEBUG_PUDA, "%s: error resource type = 0x%x\n",
@@ -731,45 +814,14 @@ void i40iw_puda_dele_resources(struct i40iw_sc_dev *dev,
case PUDA_HASH_CRC_COMPLETE:
i40iw_free_hash_desc(rsrc->hash_desc);
case PUDA_QP_CREATED:
- do {
- if (reset)
- break;
- ret = dev->iw_priv_qp_ops->qp_destroy(&rsrc->qp,
- 0, false, true, true);
- if (ret)
- i40iw_debug(rsrc->dev, I40IW_DEBUG_PUDA,
- "%s error ieq qp destroy\n",
- __func__);
-
- ret = dev->cqp_ops->poll_for_cqp_op_done(dev->cqp,
- I40IW_CQP_OP_DESTROY_QP,
- &compl_info);
- if (ret)
- i40iw_debug(rsrc->dev, I40IW_DEBUG_PUDA,
- "%s error ieq qp destroy done\n",
- __func__);
- } while (0);
+ if (!reset)
+ i40iw_puda_free_qp(rsrc);
i40iw_free_dma_mem(dev->hw, &rsrc->qpmem);
/* fallthrough */
case PUDA_CQ_CREATED:
- do {
- if (reset)
- break;
- ret = dev->iw_priv_cq_ops->cq_destroy(&rsrc->cq, 0, true);
- if (ret)
- i40iw_debug(rsrc->dev, I40IW_DEBUG_PUDA,
- "%s error ieq cq destroy\n",
- __func__);
-
- ret = dev->cqp_ops->poll_for_cqp_op_done(dev->cqp,
- I40IW_CQP_OP_DESTROY_CQ,
- &compl_info);
- if (ret)
- i40iw_debug(rsrc->dev, I40IW_DEBUG_PUDA,
- "%s error ieq qp destroy done\n",
- __func__);
- } while (0);
+ if (!reset)
+ i40iw_puda_free_cq(rsrc);
i40iw_free_dma_mem(dev->hw, &rsrc->cqmem);
break;
@@ -825,9 +877,10 @@ static enum i40iw_status_code i40iw_puda_allocbufs(struct i40iw_puda_rsrc *rsrc,
* @dev: iwarp device
* @info: resource information
*/
-enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_dev *dev,
+enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi,
struct i40iw_puda_rsrc_info *info)
{
+ struct i40iw_sc_dev *dev = vsi->dev;
enum i40iw_status_code ret = 0;
struct i40iw_puda_rsrc *rsrc;
u32 pudasize;
@@ -840,10 +893,10 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_dev *dev,
rqwridsize = info->rq_size * 8;
switch (info->type) {
case I40IW_PUDA_RSRC_TYPE_ILQ:
- vmem = &dev->ilq_mem;
+ vmem = &vsi->ilq_mem;
break;
case I40IW_PUDA_RSRC_TYPE_IEQ:
- vmem = &dev->ieq_mem;
+ vmem = &vsi->ieq_mem;
break;
default:
return I40IW_NOT_SUPPORTED;
@@ -856,22 +909,22 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_dev *dev,
rsrc = (struct i40iw_puda_rsrc *)vmem->va;
spin_lock_init(&rsrc->bufpool_lock);
if (info->type == I40IW_PUDA_RSRC_TYPE_ILQ) {
- dev->ilq = (struct i40iw_puda_rsrc *)vmem->va;
- dev->ilq_count = info->count;
+ vsi->ilq = (struct i40iw_puda_rsrc *)vmem->va;
+ vsi->ilq_count = info->count;
rsrc->receive = info->receive;
rsrc->xmit_complete = info->xmit_complete;
} else {
- vmem = &dev->ieq_mem;
- dev->ieq_count = info->count;
- dev->ieq = (struct i40iw_puda_rsrc *)vmem->va;
+ vmem = &vsi->ieq_mem;
+ vsi->ieq_count = info->count;
+ vsi->ieq = (struct i40iw_puda_rsrc *)vmem->va;
rsrc->receive = i40iw_ieq_receive;
rsrc->xmit_complete = i40iw_ieq_tx_compl;
}
+ rsrc->ceq_valid = info->ceq_valid;
rsrc->type = info->type;
rsrc->sq_wrtrk_array = (struct i40iw_sq_uk_wr_trk_info *)((u8 *)vmem->va + pudasize);
rsrc->rq_wrid_array = (u64 *)((u8 *)vmem->va + pudasize + sqwridsize);
- rsrc->mss = info->mss;
/* Initialize all ieq lists */
INIT_LIST_HEAD(&rsrc->bufpool);
INIT_LIST_HEAD(&rsrc->txpend);
@@ -885,6 +938,7 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_dev *dev,
rsrc->cq_size = info->rq_size + info->sq_size;
rsrc->buf_size = info->buf_size;
rsrc->dev = dev;
+ rsrc->vsi = vsi;
ret = i40iw_puda_cq_create(rsrc);
if (!ret) {
@@ -919,7 +973,7 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_dev *dev,
dev->ccq_ops->ccq_arm(&rsrc->cq);
return ret;
error:
- i40iw_puda_dele_resources(dev, info->type, false);
+ i40iw_puda_dele_resources(vsi, info->type, false);
return ret;
}
@@ -1131,7 +1185,7 @@ static enum i40iw_status_code i40iw_ieq_handle_partial(struct i40iw_puda_rsrc *i
list_add(&buf->list, &pbufl);
status = i40iw_ieq_create_pbufl(pfpdu, rxlist, &pbufl, buf, fpdu_len);
- if (!status)
+ if (status)
goto error;
txbuf = i40iw_puda_get_bufpool(ieq);
@@ -1332,7 +1386,7 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq,
}
if (pfpdu->mode && (fps != pfpdu->fps)) {
/* clean up qp as it is new partial sequence */
- i40iw_ieq_cleanup_qp(ieq->dev, qp);
+ i40iw_ieq_cleanup_qp(ieq, qp);
i40iw_debug(ieq->dev, I40IW_DEBUG_IEQ,
"%s: restarting new partial\n", __func__);
pfpdu->mode = false;
@@ -1344,7 +1398,7 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq,
pfpdu->rcv_nxt = fps;
pfpdu->fps = fps;
pfpdu->mode = true;
- pfpdu->max_fpdu_data = ieq->mss;
+ pfpdu->max_fpdu_data = ieq->vsi->mss;
pfpdu->pmode_count++;
INIT_LIST_HEAD(rxlist);
i40iw_ieq_check_first_buf(buf, fps);
@@ -1379,14 +1433,14 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq,
* @dev: iwarp device
* @buf: exception buffer received
*/
-static void i40iw_ieq_receive(struct i40iw_sc_dev *dev,
+static void i40iw_ieq_receive(struct i40iw_sc_vsi *vsi,
struct i40iw_puda_buf *buf)
{
- struct i40iw_puda_rsrc *ieq = dev->ieq;
+ struct i40iw_puda_rsrc *ieq = vsi->ieq;
struct i40iw_sc_qp *qp = NULL;
u32 wqe_idx = ieq->compl_rxwqe_idx;
- qp = i40iw_ieq_get_qp(dev, buf);
+ qp = i40iw_ieq_get_qp(vsi->dev, buf);
if (!qp) {
ieq->stats_bad_qp_id++;
i40iw_puda_ret_bufpool(ieq, buf);
@@ -1404,12 +1458,12 @@ static void i40iw_ieq_receive(struct i40iw_sc_dev *dev,
/**
* i40iw_ieq_tx_compl - put back after sending completed exception buffer
- * @dev: iwarp device
+ * @vsi: pointer to the vsi structure
* @sqwrid: pointer to puda buffer
*/
-static void i40iw_ieq_tx_compl(struct i40iw_sc_dev *dev, void *sqwrid)
+static void i40iw_ieq_tx_compl(struct i40iw_sc_vsi *vsi, void *sqwrid)
{
- struct i40iw_puda_rsrc *ieq = dev->ieq;
+ struct i40iw_puda_rsrc *ieq = vsi->ieq;
struct i40iw_puda_buf *buf = (struct i40iw_puda_buf *)sqwrid;
i40iw_puda_ret_bufpool(ieq, buf);
@@ -1421,15 +1475,14 @@ static void i40iw_ieq_tx_compl(struct i40iw_sc_dev *dev, void *sqwrid)
/**
* i40iw_ieq_cleanup_qp - qp is being destroyed
- * @dev: iwarp device
+ * @ieq: ieq resource
* @qp: all pending fpdu buffers
*/
-void i40iw_ieq_cleanup_qp(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp)
+static void i40iw_ieq_cleanup_qp(struct i40iw_puda_rsrc *ieq, struct i40iw_sc_qp *qp)
{
struct i40iw_puda_buf *buf;
struct i40iw_pfpdu *pfpdu = &qp->pfpdu;
struct list_head *rxlist = &pfpdu->rxlist;
- struct i40iw_puda_rsrc *ieq = dev->ieq;
if (!pfpdu->mode)
return;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.h b/drivers/infiniband/hw/i40iw/i40iw_puda.h
index 52bf7826ce4e..dba05ce7d392 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_puda.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_puda.h
@@ -100,6 +100,7 @@ struct i40iw_puda_rsrc_info {
enum puda_resource_type type; /* ILQ or IEQ */
u32 count;
u16 pd_id;
+ bool ceq_valid;
u32 cq_id;
u32 qp_id;
u32 sq_size;
@@ -107,8 +108,8 @@ struct i40iw_puda_rsrc_info {
u16 buf_size;
u16 mss;
u32 tx_buf_cnt; /* total bufs allocated will be rq_size + tx_buf_cnt */
- void (*receive)(struct i40iw_sc_dev *, struct i40iw_puda_buf *);
- void (*xmit_complete)(struct i40iw_sc_dev *, void *);
+ void (*receive)(struct i40iw_sc_vsi *, struct i40iw_puda_buf *);
+ void (*xmit_complete)(struct i40iw_sc_vsi *, void *);
};
struct i40iw_puda_rsrc {
@@ -116,6 +117,7 @@ struct i40iw_puda_rsrc {
struct i40iw_sc_qp qp;
struct i40iw_sc_pd sc_pd;
struct i40iw_sc_dev *dev;
+ struct i40iw_sc_vsi *vsi;
struct i40iw_dma_mem cqmem;
struct i40iw_dma_mem qpmem;
struct i40iw_virt_mem ilq_mem;
@@ -123,6 +125,7 @@ struct i40iw_puda_rsrc {
enum puda_resource_type type;
u16 buf_size; /*buffer must be max datalen + tcpip hdr + mac */
u16 mss;
+ bool ceq_valid;
u32 cq_id;
u32 qp_id;
u32 sq_size;
@@ -142,8 +145,8 @@ struct i40iw_puda_rsrc {
u32 avail_buf_count; /* snapshot of currently available buffers */
spinlock_t bufpool_lock;
struct i40iw_puda_buf *alloclist;
- void (*receive)(struct i40iw_sc_dev *, struct i40iw_puda_buf *);
- void (*xmit_complete)(struct i40iw_sc_dev *, void *);
+ void (*receive)(struct i40iw_sc_vsi *, struct i40iw_puda_buf *);
+ void (*xmit_complete)(struct i40iw_sc_vsi *, void *);
/* puda stats */
u64 stats_buf_alloc_fail;
u64 stats_pkt_rcvd;
@@ -160,14 +163,13 @@ void i40iw_puda_send_buf(struct i40iw_puda_rsrc *rsrc,
struct i40iw_puda_buf *buf);
enum i40iw_status_code i40iw_puda_send(struct i40iw_sc_qp *qp,
struct i40iw_puda_send_info *info);
-enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_dev *dev,
+enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi,
struct i40iw_puda_rsrc_info *info);
-void i40iw_puda_dele_resources(struct i40iw_sc_dev *dev,
+void i40iw_puda_dele_resources(struct i40iw_sc_vsi *vsi,
enum puda_resource_type type,
bool reset);
enum i40iw_status_code i40iw_puda_poll_completion(struct i40iw_sc_dev *dev,
struct i40iw_sc_cq *cq, u32 *compl_err);
-void i40iw_ieq_cleanup_qp(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
struct i40iw_sc_qp *i40iw_ieq_get_qp(struct i40iw_sc_dev *dev,
struct i40iw_puda_buf *buf);
@@ -180,4 +182,8 @@ void i40iw_ieq_mpa_crc_ae(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
void i40iw_free_hash_desc(struct shash_desc *desc);
void i40iw_ieq_update_tcpip_info(struct i40iw_puda_buf *buf, u16 length,
u32 seqnum);
+enum i40iw_status_code i40iw_cqp_qp_create_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
+enum i40iw_status_code i40iw_cqp_cq_create_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_cq *cq);
+void i40iw_cqp_qp_destroy_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp);
+void i40iw_cqp_cq_destroy_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_cq *cq);
#endif
diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h
index 2b1a04e9ca3c..f3f8e9cc3c05 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_type.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_type.h
@@ -61,7 +61,7 @@ struct i40iw_cq_shadow_area {
struct i40iw_sc_dev;
struct i40iw_hmc_info;
-struct i40iw_dev_pestat;
+struct i40iw_vsi_pestat;
struct i40iw_cqp_ops;
struct i40iw_ccq_ops;
@@ -74,6 +74,11 @@ struct i40iw_priv_qp_ops;
struct i40iw_priv_cq_ops;
struct i40iw_hmc_ops;
+enum i40iw_page_size {
+ I40IW_PAGE_SIZE_4K,
+ I40IW_PAGE_SIZE_2M
+};
+
enum i40iw_resource_indicator_type {
I40IW_RSRC_INDICATOR_TYPE_ADAPTER = 0,
I40IW_RSRC_INDICATOR_TYPE_CQ,
@@ -186,7 +191,7 @@ enum i40iw_debug_flag {
I40IW_DEBUG_ALL = 0xFFFFFFFF
};
-enum i40iw_hw_stat_index_32b {
+enum i40iw_hw_stats_index_32b {
I40IW_HW_STAT_INDEX_IP4RXDISCARD = 0,
I40IW_HW_STAT_INDEX_IP4RXTRUNC,
I40IW_HW_STAT_INDEX_IP4TXNOROUTE,
@@ -199,7 +204,7 @@ enum i40iw_hw_stat_index_32b {
I40IW_HW_STAT_INDEX_MAX_32
};
-enum i40iw_hw_stat_index_64b {
+enum i40iw_hw_stats_index_64b {
I40IW_HW_STAT_INDEX_IP4RXOCTS = 0,
I40IW_HW_STAT_INDEX_IP4RXPKTS,
I40IW_HW_STAT_INDEX_IP4RXFRAGS,
@@ -229,32 +234,23 @@ enum i40iw_hw_stat_index_64b {
I40IW_HW_STAT_INDEX_MAX_64
};
-struct i40iw_dev_hw_stat_offsets {
- u32 stat_offset_32[I40IW_HW_STAT_INDEX_MAX_32];
- u32 stat_offset_64[I40IW_HW_STAT_INDEX_MAX_64];
+struct i40iw_dev_hw_stats_offsets {
+ u32 stats_offset_32[I40IW_HW_STAT_INDEX_MAX_32];
+ u32 stats_offset_64[I40IW_HW_STAT_INDEX_MAX_64];
};
struct i40iw_dev_hw_stats {
- u64 stat_value_32[I40IW_HW_STAT_INDEX_MAX_32];
- u64 stat_value_64[I40IW_HW_STAT_INDEX_MAX_64];
-};
-
-struct i40iw_device_pestat_ops {
- void (*iw_hw_stat_init)(struct i40iw_dev_pestat *, u8, struct i40iw_hw *, bool);
- void (*iw_hw_stat_read_32)(struct i40iw_dev_pestat *, enum i40iw_hw_stat_index_32b, u64 *);
- void (*iw_hw_stat_read_64)(struct i40iw_dev_pestat *, enum i40iw_hw_stat_index_64b, u64 *);
- void (*iw_hw_stat_read_all)(struct i40iw_dev_pestat *, struct i40iw_dev_hw_stats *);
- void (*iw_hw_stat_refresh_all)(struct i40iw_dev_pestat *);
+ u64 stats_value_32[I40IW_HW_STAT_INDEX_MAX_32];
+ u64 stats_value_64[I40IW_HW_STAT_INDEX_MAX_64];
};
-struct i40iw_dev_pestat {
+struct i40iw_vsi_pestat {
struct i40iw_hw *hw;
- struct i40iw_device_pestat_ops ops;
struct i40iw_dev_hw_stats hw_stats;
struct i40iw_dev_hw_stats last_read_hw_stats;
- struct i40iw_dev_hw_stat_offsets hw_stat_offsets;
+ struct i40iw_dev_hw_stats_offsets hw_stats_offsets;
struct timer_list stats_timer;
- spinlock_t stats_lock; /* rdma stats lock */
+ spinlock_t lock; /* rdma stats lock */
};
struct i40iw_hw {
@@ -350,6 +346,7 @@ struct i40iw_sc_cq {
u64 cq_pa;
u64 shadow_area_pa;
struct i40iw_sc_dev *dev;
+ struct i40iw_sc_vsi *vsi;
void *pbl_list;
void *back_cq;
u32 ceq_id;
@@ -373,6 +370,7 @@ struct i40iw_sc_qp {
u64 shadow_area_pa;
u64 q2_pa;
struct i40iw_sc_dev *dev;
+ struct i40iw_sc_vsi *vsi;
struct i40iw_sc_pd *pd;
u64 *hw_host_ctx;
void *llp_stream_handle;
@@ -397,6 +395,9 @@ struct i40iw_sc_qp {
bool virtual_map;
bool flush_sq;
bool flush_rq;
+ u8 user_pri;
+ struct list_head list;
+ bool on_qoslist;
bool sq_flush;
enum i40iw_flush_opcode flush_code;
enum i40iw_term_eventtypes eventtype;
@@ -424,10 +425,16 @@ struct i40iw_vchnl_vf_msg_buffer {
char parm_buffer[I40IW_VCHNL_MAX_VF_MSG_SIZE - 1];
};
+struct i40iw_qos {
+ struct list_head qplist;
+ spinlock_t lock; /* qos list */
+ u16 qs_handle;
+};
+
struct i40iw_vfdev {
struct i40iw_sc_dev *pf_dev;
u8 *hmc_info_mem;
- struct i40iw_dev_pestat dev_pestat;
+ struct i40iw_vsi_pestat pestat;
struct i40iw_hmc_pble_info *pble_info;
struct i40iw_hmc_info hmc_info;
struct i40iw_vchnl_vf_msg_buffer vf_msg_buffer;
@@ -441,11 +448,28 @@ struct i40iw_vfdev {
bool stats_initialized;
};
+#define I40IW_INVALID_FCN_ID 0xff
+struct i40iw_sc_vsi {
+ struct i40iw_sc_dev *dev;
+ void *back_vsi; /* Owned by OS */
+ u32 ilq_count;
+ struct i40iw_virt_mem ilq_mem;
+ struct i40iw_puda_rsrc *ilq;
+ u32 ieq_count;
+ struct i40iw_virt_mem ieq_mem;
+ struct i40iw_puda_rsrc *ieq;
+ u16 mss;
+ u8 fcn_id;
+ bool stats_fcn_id_alloc;
+ struct i40iw_qos qos[I40IW_MAX_USER_PRIORITY];
+ struct i40iw_vsi_pestat *pestat;
+};
+
struct i40iw_sc_dev {
struct list_head cqp_cmd_head; /* head of the CQP command list */
spinlock_t cqp_lock; /* cqp list sync */
struct i40iw_dev_uk dev_uk;
- struct i40iw_dev_pestat dev_pestat;
+ bool fcn_id_array[I40IW_MAX_STATS_COUNT];
struct i40iw_dma_mem vf_fpm_query_buf[I40IW_MAX_PE_ENABLED_VF_COUNT];
u64 fpm_query_buf_pa;
u64 fpm_commit_buf_pa;
@@ -472,17 +496,9 @@ struct i40iw_sc_dev {
struct i40iw_cqp_misc_ops *cqp_misc_ops;
struct i40iw_hmc_ops *hmc_ops;
struct i40iw_vchnl_if vchnl_if;
- u32 ilq_count;
- struct i40iw_virt_mem ilq_mem;
- struct i40iw_puda_rsrc *ilq;
- u32 ieq_count;
- struct i40iw_virt_mem ieq_mem;
- struct i40iw_puda_rsrc *ieq;
-
const struct i40iw_vf_cqp_ops *iw_vf_cqp_ops;
struct i40iw_hmc_fpm_misc hmc_fpm_misc;
- u16 qs_handle;
u32 debug_mask;
u16 exception_lan_queue;
u8 hmc_fn_id;
@@ -556,6 +572,19 @@ struct i40iw_l2params {
u16 mss;
};
+struct i40iw_vsi_init_info {
+ struct i40iw_sc_dev *dev;
+ void *back_vsi;
+ struct i40iw_l2params *params;
+};
+
+struct i40iw_vsi_stats_info {
+ struct i40iw_vsi_pestat *pestat;
+ u8 fcn_id;
+ bool alloc_fcn_id;
+ bool stats_initialize;
+};
+
struct i40iw_device_init_info {
u64 fpm_query_buf_pa;
u64 fpm_commit_buf_pa;
@@ -564,7 +593,6 @@ struct i40iw_device_init_info {
struct i40iw_hw *hw;
void __iomem *bar0;
enum i40iw_status_code (*vchnl_send)(struct i40iw_sc_dev *, u32, u8 *, u16);
- u16 qs_handle;
u16 exception_lan_queue;
u8 hmc_fn_id;
bool is_pf;
@@ -722,6 +750,8 @@ struct i40iw_qp_host_ctx_info {
bool iwarp_info_valid;
bool err_rq_idx_valid;
u16 err_rq_idx;
+ bool add_to_qoslist;
+ u8 user_pri;
};
struct i40iw_aeqe_info {
@@ -814,6 +844,7 @@ struct i40iw_register_shared_stag {
struct i40iw_qp_init_info {
struct i40iw_qp_uk_init_info qp_uk_init_info;
struct i40iw_sc_pd *pd;
+ struct i40iw_sc_vsi *vsi;
u64 *host_ctx;
u8 *q2;
u64 sq_pa;
@@ -880,13 +911,14 @@ enum i40iw_quad_hash_manage_type {
};
struct i40iw_qhash_table_info {
+ struct i40iw_sc_vsi *vsi;
enum i40iw_quad_hash_manage_type manage;
enum i40iw_quad_entry_type entry_type;
bool vlan_valid;
bool ipv4_valid;
u8 mac_addr[6];
u16 vlan_id;
- u16 qs_handle;
+ u8 user_pri;
u32 qp_num;
u32 dest_ip[4];
u32 src_ip[4];
@@ -976,7 +1008,7 @@ struct i40iw_cqp_query_fpm_values {
struct i40iw_cqp_ops {
enum i40iw_status_code (*cqp_init)(struct i40iw_sc_cqp *,
struct i40iw_cqp_init_info *);
- enum i40iw_status_code (*cqp_create)(struct i40iw_sc_cqp *, bool, u16 *, u16 *);
+ enum i40iw_status_code (*cqp_create)(struct i40iw_sc_cqp *, u16 *, u16 *);
void (*cqp_post_sq)(struct i40iw_sc_cqp *);
u64 *(*cqp_get_next_send_wqe)(struct i40iw_sc_cqp *, u64 scratch);
enum i40iw_status_code (*cqp_destroy)(struct i40iw_sc_cqp *);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c
index 4d28c3cb03cc..4376cd628774 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c
@@ -175,12 +175,10 @@ u64 *i40iw_qp_get_next_send_wqe(struct i40iw_qp_uk *qp,
if (!*wqe_idx)
qp->swqe_polarity = !qp->swqe_polarity;
}
-
- for (i = 0; i < wqe_size / I40IW_QP_WQE_MIN_SIZE; i++) {
- I40IW_RING_MOVE_HEAD(qp->sq_ring, ret_code);
- if (ret_code)
- return NULL;
- }
+ I40IW_RING_MOVE_HEAD_BY_COUNT(qp->sq_ring,
+ wqe_size / I40IW_QP_WQE_MIN_SIZE, ret_code);
+ if (ret_code)
+ return NULL;
wqe = qp->sq_base[*wqe_idx].elem;
@@ -430,7 +428,7 @@ static enum i40iw_status_code i40iw_inline_rdma_write(struct i40iw_qp_uk *qp,
struct i40iw_inline_rdma_write *op_info;
u64 *push;
u64 header = 0;
- u32 i, wqe_idx;
+ u32 wqe_idx;
enum i40iw_status_code ret_code;
bool read_fence = false;
u8 wqe_size;
@@ -465,14 +463,12 @@ static enum i40iw_status_code i40iw_inline_rdma_write(struct i40iw_qp_uk *qp,
src = (u8 *)(op_info->data);
if (op_info->len <= 16) {
- for (i = 0; i < op_info->len; i++, src++, dest++)
- *dest = *src;
+ memcpy(dest, src, op_info->len);
} else {
- for (i = 0; i < 16; i++, src++, dest++)
- *dest = *src;
+ memcpy(dest, src, 16);
+ src += 16;
dest = (u8 *)wqe + 32;
- for (; i < op_info->len; i++, src++, dest++)
- *dest = *src;
+ memcpy(dest, src, op_info->len - 16);
}
wmb(); /* make sure WQE is populated before valid bit is set */
@@ -507,7 +503,7 @@ static enum i40iw_status_code i40iw_inline_send(struct i40iw_qp_uk *qp,
u8 *dest, *src;
struct i40iw_post_inline_send *op_info;
u64 header;
- u32 wqe_idx, i;
+ u32 wqe_idx;
enum i40iw_status_code ret_code;
bool read_fence = false;
u8 wqe_size;
@@ -540,14 +536,12 @@ static enum i40iw_status_code i40iw_inline_send(struct i40iw_qp_uk *qp,
src = (u8 *)(op_info->data);
if (op_info->len <= 16) {
- for (i = 0; i < op_info->len; i++, src++, dest++)
- *dest = *src;
+ memcpy(dest, src, op_info->len);
} else {
- for (i = 0; i < 16; i++, src++, dest++)
- *dest = *src;
+ memcpy(dest, src, 16);
+ src += 16;
dest = (u8 *)wqe + 32;
- for (; i < op_info->len; i++, src++, dest++)
- *dest = *src;
+ memcpy(dest, src, op_info->len - 16);
}
wmb(); /* make sure WQE is populated before valid bit is set */
@@ -1190,12 +1184,8 @@ enum i40iw_status_code i40iw_inline_data_size_to_wqesize(u32 data_size,
if (data_size <= 16)
*wqe_size = I40IW_QP_WQE_MIN_SIZE;
- else if (data_size <= 48)
- *wqe_size = 64;
- else if (data_size <= 80)
- *wqe_size = 96;
else
- *wqe_size = 128;
+ *wqe_size = 64;
return 0;
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_user.h b/drivers/infiniband/hw/i40iw/i40iw_user.h
index 276bcefffd7e..80d9f464f65e 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_user.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_user.h
@@ -72,12 +72,12 @@ enum i40iw_device_capabilities_const {
I40IW_MAX_SQ_PAYLOAD_SIZE = 2145386496,
I40IW_MAX_INLINE_DATA_SIZE = 48,
I40IW_MAX_PUSHMODE_INLINE_DATA_SIZE = 48,
- I40IW_MAX_IRD_SIZE = 32,
- I40IW_QPCTX_ENCD_MAXIRD = 3,
+ I40IW_MAX_IRD_SIZE = 63,
+ I40IW_MAX_ORD_SIZE = 127,
I40IW_MAX_WQ_ENTRIES = 2048,
- I40IW_MAX_ORD_SIZE = 32,
I40IW_Q2_BUFFER_SIZE = (248 + 100),
- I40IW_QP_CTX_SIZE = 248
+ I40IW_QP_CTX_SIZE = 248,
+ I40IW_MAX_PDS = 32768
};
#define i40iw_handle void *
@@ -96,12 +96,6 @@ enum i40iw_device_capabilities_const {
#define i40iw_physical_fragment u64
#define i40iw_address_list u64 *
-#define I40IW_CREATE_STAG(index, key) (((index) << 8) + (key))
-
-#define I40IW_STAG_KEY_FROM_STAG(stag) ((stag) && 0x000000FF)
-
-#define I40IW_STAG_INDEX_FROM_STAG(stag) (((stag) && 0xFFFFFF00) >> 8)
-
#define I40IW_MAX_MR_SIZE 0x10000000000L
struct i40iw_qp_uk;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c
index 6fd043b1d714..0f5d43d1f5fc 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c
@@ -153,6 +153,7 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
struct i40iw_device *iwdev;
struct i40iw_handler *hdl;
u32 local_ipaddr;
+ u32 action = I40IW_ARP_ADD;
hdl = i40iw_find_netdev(event_netdev);
if (!hdl)
@@ -164,44 +165,25 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
if (netdev != event_netdev)
return NOTIFY_DONE;
+ if (upper_dev)
+ local_ipaddr = ntohl(
+ ((struct in_device *)upper_dev->ip_ptr)->ifa_list->ifa_address);
+ else
+ local_ipaddr = ntohl(ifa->ifa_address);
switch (event) {
case NETDEV_DOWN:
- if (upper_dev)
- local_ipaddr = ntohl(
- ((struct in_device *)upper_dev->ip_ptr)->ifa_list->ifa_address);
- else
- local_ipaddr = ntohl(ifa->ifa_address);
- i40iw_manage_arp_cache(iwdev,
- netdev->dev_addr,
- &local_ipaddr,
- true,
- I40IW_ARP_DELETE);
- return NOTIFY_OK;
+ action = I40IW_ARP_DELETE;
+ /* Fall through */
case NETDEV_UP:
- if (upper_dev)
- local_ipaddr = ntohl(
- ((struct in_device *)upper_dev->ip_ptr)->ifa_list->ifa_address);
- else
- local_ipaddr = ntohl(ifa->ifa_address);
- i40iw_manage_arp_cache(iwdev,
- netdev->dev_addr,
- &local_ipaddr,
- true,
- I40IW_ARP_ADD);
- break;
+ /* Fall through */
case NETDEV_CHANGEADDR:
- /* Add the address to the IP table */
- if (upper_dev)
- local_ipaddr = ntohl(
- ((struct in_device *)upper_dev->ip_ptr)->ifa_list->ifa_address);
- else
- local_ipaddr = ntohl(ifa->ifa_address);
-
i40iw_manage_arp_cache(iwdev,
netdev->dev_addr,
&local_ipaddr,
true,
- I40IW_ARP_ADD);
+ action);
+ i40iw_if_notify(iwdev, netdev, &local_ipaddr, true,
+ (action == I40IW_ARP_ADD) ? true : false);
break;
default:
break;
@@ -225,6 +207,7 @@ int i40iw_inet6addr_event(struct notifier_block *notifier,
struct i40iw_device *iwdev;
struct i40iw_handler *hdl;
u32 local_ipaddr6[4];
+ u32 action = I40IW_ARP_ADD;
hdl = i40iw_find_netdev(event_netdev);
if (!hdl)
@@ -235,24 +218,21 @@ int i40iw_inet6addr_event(struct notifier_block *notifier,
if (netdev != event_netdev)
return NOTIFY_DONE;
+ i40iw_copy_ip_ntohl(local_ipaddr6, ifa->addr.in6_u.u6_addr32);
switch (event) {
case NETDEV_DOWN:
- i40iw_copy_ip_ntohl(local_ipaddr6, ifa->addr.in6_u.u6_addr32);
- i40iw_manage_arp_cache(iwdev,
- netdev->dev_addr,
- local_ipaddr6,
- false,
- I40IW_ARP_DELETE);
- return NOTIFY_OK;
+ action = I40IW_ARP_DELETE;
+ /* Fall through */
case NETDEV_UP:
/* Fall through */
case NETDEV_CHANGEADDR:
- i40iw_copy_ip_ntohl(local_ipaddr6, ifa->addr.in6_u.u6_addr32);
i40iw_manage_arp_cache(iwdev,
netdev->dev_addr,
local_ipaddr6,
false,
- I40IW_ARP_ADD);
+ action);
+ i40iw_if_notify(iwdev, netdev, local_ipaddr6, false,
+ (action == I40IW_ARP_ADD) ? true : false);
break;
default:
break;
@@ -392,6 +372,7 @@ static void i40iw_free_qp(struct i40iw_cqp_request *cqp_request, u32 num)
i40iw_rem_pdusecount(iwqp->iwpd, iwdev);
i40iw_free_qp_resources(iwdev, iwqp, qp_num);
+ i40iw_rem_devusecount(iwdev);
}
/**
@@ -415,7 +396,10 @@ static int i40iw_wait_event(struct i40iw_device *iwdev,
i40iw_pr_err("error cqp command 0x%x timed out ret = %d\n",
info->cqp_cmd, timeout_ret);
err_code = -ETIME;
- i40iw_request_reset(iwdev);
+ if (!iwdev->reset) {
+ iwdev->reset = true;
+ i40iw_request_reset(iwdev);
+ }
goto done;
}
cqp_error = cqp_request->compl_info.error;
@@ -445,6 +429,11 @@ enum i40iw_status_code i40iw_handle_cqp_op(struct i40iw_device *iwdev,
struct cqp_commands_info *info = &cqp_request->info;
int err_code = 0;
+ if (iwdev->reset) {
+ i40iw_free_cqp_request(&iwdev->cqp, cqp_request);
+ return I40IW_ERR_CQP_COMPL_ERROR;
+ }
+
status = i40iw_process_cqp_cmd(dev, info);
if (status) {
i40iw_pr_err("error cqp command 0x%x failed\n", info->cqp_cmd);
@@ -459,6 +448,26 @@ enum i40iw_status_code i40iw_handle_cqp_op(struct i40iw_device *iwdev,
}
/**
+ * i40iw_add_devusecount - add dev refcount
+ * @iwdev: dev for refcount
+ */
+void i40iw_add_devusecount(struct i40iw_device *iwdev)
+{
+ atomic64_inc(&iwdev->use_count);
+}
+
+/**
+ * i40iw_rem_devusecount - decrement refcount for dev
+ * @iwdev: device
+ */
+void i40iw_rem_devusecount(struct i40iw_device *iwdev)
+{
+ if (!atomic64_dec_and_test(&iwdev->use_count))
+ return;
+ wake_up(&iwdev->close_wq);
+}
+
+/**
* i40iw_add_pdusecount - add pd refcount
* @iwpd: pd for refcount
*/
@@ -712,6 +721,51 @@ enum i40iw_status_code i40iw_cqp_sds_cmd(struct i40iw_sc_dev *dev,
}
/**
+ * i40iw_qp_suspend_resume - cqp command for suspend/resume
+ * @dev: hardware control device structure
+ * @qp: hardware control qp
+ * @suspend: flag if suspend or resume
+ */
+void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp, bool suspend)
+{
+ struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
+ struct i40iw_cqp_request *cqp_request;
+ struct i40iw_sc_cqp *cqp = dev->cqp;
+ struct cqp_commands_info *cqp_info;
+ enum i40iw_status_code status;
+
+ cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false);
+ if (!cqp_request)
+ return;
+
+ cqp_info = &cqp_request->info;
+ cqp_info->cqp_cmd = (suspend) ? OP_SUSPEND : OP_RESUME;
+ cqp_info->in.u.suspend_resume.cqp = cqp;
+ cqp_info->in.u.suspend_resume.qp = qp;
+ cqp_info->in.u.suspend_resume.scratch = (uintptr_t)cqp_request;
+ status = i40iw_handle_cqp_op(iwdev, cqp_request);
+ if (status)
+ i40iw_pr_err("CQP-OP QP Suspend/Resume fail");
+}
+
+/**
+ * i40iw_qp_mss_modify - modify mss for qp
+ * @dev: hardware control device structure
+ * @qp: hardware control qp
+ */
+void i40iw_qp_mss_modify(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp)
+{
+ struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
+ struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp;
+ struct i40iw_modify_qp_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.mss_change = true;
+ info.new_mss = qp->vsi->mss;
+ i40iw_hw_modify_qp(iwdev, iwqp, &info, false);
+}
+
+/**
* i40iw_term_modify_qp - modify qp for term message
* @qp: hardware control qp
* @next_state: qp's next state
@@ -769,6 +823,7 @@ static void i40iw_terminate_timeout(unsigned long context)
struct i40iw_sc_qp *qp = (struct i40iw_sc_qp *)&iwqp->sc_qp;
i40iw_terminate_done(qp, 1);
+ i40iw_rem_ref(&iwqp->ibqp);
}
/**
@@ -780,6 +835,7 @@ void i40iw_terminate_start_timer(struct i40iw_sc_qp *qp)
struct i40iw_qp *iwqp;
iwqp = (struct i40iw_qp *)qp->back_qp;
+ i40iw_add_ref(&iwqp->ibqp);
init_timer(&iwqp->terminate_timer);
iwqp->terminate_timer.function = i40iw_terminate_timeout;
iwqp->terminate_timer.expires = jiffies + HZ;
@@ -796,7 +852,8 @@ void i40iw_terminate_del_timer(struct i40iw_sc_qp *qp)
struct i40iw_qp *iwqp;
iwqp = (struct i40iw_qp *)qp->back_qp;
- del_timer(&iwqp->terminate_timer);
+ if (del_timer(&iwqp->terminate_timer))
+ i40iw_rem_ref(&iwqp->ibqp);
}
/**
@@ -1011,6 +1068,116 @@ enum i40iw_status_code i40iw_vf_wait_vchnl_resp(struct i40iw_sc_dev *dev)
}
/**
+ * i40iw_cqp_cq_create_cmd - create a cq for the cqp
+ * @dev: device pointer
+ * @cq: pointer to created cq
+ */
+enum i40iw_status_code i40iw_cqp_cq_create_cmd(struct i40iw_sc_dev *dev,
+ struct i40iw_sc_cq *cq)
+{
+ struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
+ struct i40iw_cqp *iwcqp = &iwdev->cqp;
+ struct i40iw_cqp_request *cqp_request;
+ struct cqp_commands_info *cqp_info;
+ enum i40iw_status_code status;
+
+ cqp_request = i40iw_get_cqp_request(iwcqp, true);
+ if (!cqp_request)
+ return I40IW_ERR_NO_MEMORY;
+
+ cqp_info = &cqp_request->info;
+ cqp_info->cqp_cmd = OP_CQ_CREATE;
+ cqp_info->post_sq = 1;
+ cqp_info->in.u.cq_create.cq = cq;
+ cqp_info->in.u.cq_create.scratch = (uintptr_t)cqp_request;
+ status = i40iw_handle_cqp_op(iwdev, cqp_request);
+ if (status)
+ i40iw_pr_err("CQP-OP Create QP fail");
+
+ return status;
+}
+
+/**
+ * i40iw_cqp_qp_create_cmd - create a qp for the cqp
+ * @dev: device pointer
+ * @qp: pointer to created qp
+ */
+enum i40iw_status_code i40iw_cqp_qp_create_cmd(struct i40iw_sc_dev *dev,
+ struct i40iw_sc_qp *qp)
+{
+ struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
+ struct i40iw_cqp *iwcqp = &iwdev->cqp;
+ struct i40iw_cqp_request *cqp_request;
+ struct cqp_commands_info *cqp_info;
+ struct i40iw_create_qp_info *qp_info;
+ enum i40iw_status_code status;
+
+ cqp_request = i40iw_get_cqp_request(iwcqp, true);
+ if (!cqp_request)
+ return I40IW_ERR_NO_MEMORY;
+
+ cqp_info = &cqp_request->info;
+ qp_info = &cqp_request->info.in.u.qp_create.info;
+
+ memset(qp_info, 0, sizeof(*qp_info));
+
+ qp_info->cq_num_valid = true;
+ qp_info->next_iwarp_state = I40IW_QP_STATE_RTS;
+
+ cqp_info->cqp_cmd = OP_QP_CREATE;
+ cqp_info->post_sq = 1;
+ cqp_info->in.u.qp_create.qp = qp;
+ cqp_info->in.u.qp_create.scratch = (uintptr_t)cqp_request;
+ status = i40iw_handle_cqp_op(iwdev, cqp_request);
+ if (status)
+ i40iw_pr_err("CQP-OP QP create fail");
+ return status;
+}
+
+/**
+ * i40iw_cqp_cq_destroy_cmd - destroy the cqp cq
+ * @dev: device pointer
+ * @cq: pointer to cq
+ */
+void i40iw_cqp_cq_destroy_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_cq *cq)
+{
+ struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
+
+ i40iw_cq_wq_destroy(iwdev, cq);
+}
+
+/**
+ * i40iw_cqp_qp_destroy_cmd - destroy the cqp
+ * @dev: device pointer
+ * @qp: pointer to qp
+ */
+void i40iw_cqp_qp_destroy_cmd(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp)
+{
+ struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
+ struct i40iw_cqp *iwcqp = &iwdev->cqp;
+ struct i40iw_cqp_request *cqp_request;
+ struct cqp_commands_info *cqp_info;
+ enum i40iw_status_code status;
+
+ cqp_request = i40iw_get_cqp_request(iwcqp, true);
+ if (!cqp_request)
+ return;
+
+ cqp_info = &cqp_request->info;
+ memset(cqp_info, 0, sizeof(*cqp_info));
+
+ cqp_info->cqp_cmd = OP_QP_DESTROY;
+ cqp_info->post_sq = 1;
+ cqp_info->in.u.qp_destroy.qp = qp;
+ cqp_info->in.u.qp_destroy.scratch = (uintptr_t)cqp_request;
+ cqp_info->in.u.qp_destroy.remove_hash_idx = true;
+ status = i40iw_handle_cqp_op(iwdev, cqp_request);
+ if (status)
+ i40iw_pr_err("CQP QP_DESTROY fail");
+}
+
+
+/**
* i40iw_ieq_mpa_crc_ae - generate AE for crc error
* @dev: hardware control device structure
* @qp: hardware control qp
@@ -1208,7 +1375,7 @@ enum i40iw_status_code i40iw_puda_get_tcpip_info(struct i40iw_puda_completion_in
buf->totallen = pkt_len + buf->maclen;
- if (info->payload_len < buf->totallen - 4) {
+ if (info->payload_len < buf->totallen) {
i40iw_pr_err("payload_len = 0x%x totallen expected0x%x\n",
info->payload_len, buf->totallen);
return I40IW_ERR_INVALID_SIZE;
@@ -1224,27 +1391,29 @@ enum i40iw_status_code i40iw_puda_get_tcpip_info(struct i40iw_puda_completion_in
/**
* i40iw_hw_stats_timeout - Stats timer-handler which updates all HW stats
- * @dev: hardware control device structure
+ * @vsi: pointer to the vsi structure
*/
-static void i40iw_hw_stats_timeout(unsigned long dev)
+static void i40iw_hw_stats_timeout(unsigned long vsi)
{
- struct i40iw_sc_dev *pf_dev = (struct i40iw_sc_dev *)dev;
- struct i40iw_dev_pestat *pf_devstat = &pf_dev->dev_pestat;
- struct i40iw_dev_pestat *vf_devstat = NULL;
+ struct i40iw_sc_vsi *sc_vsi = (struct i40iw_sc_vsi *)vsi;
+ struct i40iw_sc_dev *pf_dev = sc_vsi->dev;
+ struct i40iw_vsi_pestat *pf_devstat = sc_vsi->pestat;
+ struct i40iw_vsi_pestat *vf_devstat = NULL;
u16 iw_vf_idx;
unsigned long flags;
/*PF*/
- pf_devstat->ops.iw_hw_stat_read_all(pf_devstat, &pf_devstat->hw_stats);
+ i40iw_hw_stats_read_all(pf_devstat, &pf_devstat->hw_stats);
+
for (iw_vf_idx = 0; iw_vf_idx < I40IW_MAX_PE_ENABLED_VF_COUNT; iw_vf_idx++) {
- spin_lock_irqsave(&pf_devstat->stats_lock, flags);
+ spin_lock_irqsave(&pf_devstat->lock, flags);
if (pf_dev->vf_dev[iw_vf_idx]) {
if (pf_dev->vf_dev[iw_vf_idx]->stats_initialized) {
- vf_devstat = &pf_dev->vf_dev[iw_vf_idx]->dev_pestat;
- vf_devstat->ops.iw_hw_stat_read_all(vf_devstat, &vf_devstat->hw_stats);
+ vf_devstat = &pf_dev->vf_dev[iw_vf_idx]->pestat;
+ i40iw_hw_stats_read_all(vf_devstat, &vf_devstat->hw_stats);
}
}
- spin_unlock_irqrestore(&pf_devstat->stats_lock, flags);
+ spin_unlock_irqrestore(&pf_devstat->lock, flags);
}
mod_timer(&pf_devstat->stats_timer,
@@ -1253,26 +1422,26 @@ static void i40iw_hw_stats_timeout(unsigned long dev)
/**
* i40iw_hw_stats_start_timer - Start periodic stats timer
- * @dev: hardware control device structure
+ * @vsi: pointer to the vsi structure
*/
-void i40iw_hw_stats_start_timer(struct i40iw_sc_dev *dev)
+void i40iw_hw_stats_start_timer(struct i40iw_sc_vsi *vsi)
{
- struct i40iw_dev_pestat *devstat = &dev->dev_pestat;
+ struct i40iw_vsi_pestat *devstat = vsi->pestat;
init_timer(&devstat->stats_timer);
devstat->stats_timer.function = i40iw_hw_stats_timeout;
- devstat->stats_timer.data = (unsigned long)dev;
+ devstat->stats_timer.data = (unsigned long)vsi;
mod_timer(&devstat->stats_timer,
jiffies + msecs_to_jiffies(STATS_TIMER_DELAY));
}
/**
- * i40iw_hw_stats_del_timer - Delete periodic stats timer
- * @dev: hardware control device structure
+ * i40iw_hw_stats_stop_timer - Delete periodic stats timer
+ * @vsi: pointer to the vsi structure
*/
-void i40iw_hw_stats_del_timer(struct i40iw_sc_dev *dev)
+void i40iw_hw_stats_stop_timer(struct i40iw_sc_vsi *vsi)
{
- struct i40iw_dev_pestat *devstat = &dev->dev_pestat;
+ struct i40iw_vsi_pestat *devstat = vsi->pestat;
del_timer_sync(&devstat->stats_timer);
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
index 6329c971c22f..7368a50bbdaa 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
@@ -37,6 +37,7 @@
#include <linux/random.h>
#include <linux/highmem.h>
#include <linux/time.h>
+#include <linux/hugetlb.h>
#include <asm/byteorder.h>
#include <net/ip.h>
#include <rdma/ib_verbs.h>
@@ -67,13 +68,13 @@ static int i40iw_query_device(struct ib_device *ibdev,
props->vendor_part_id = iwdev->ldev->pcidev->device;
props->hw_ver = (u32)iwdev->sc_dev.hw_rev;
props->max_mr_size = I40IW_MAX_OUTBOUND_MESSAGE_SIZE;
- props->max_qp = iwdev->max_qp;
+ props->max_qp = iwdev->max_qp - iwdev->used_qps;
props->max_qp_wr = (I40IW_MAX_WQ_ENTRIES >> 2) - 1;
props->max_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
- props->max_cq = iwdev->max_cq;
+ props->max_cq = iwdev->max_cq - iwdev->used_cqs;
props->max_cqe = iwdev->max_cqe;
- props->max_mr = iwdev->max_mr;
- props->max_pd = iwdev->max_pd;
+ props->max_mr = iwdev->max_mr - iwdev->used_mrs;
+ props->max_pd = iwdev->max_pd - iwdev->used_pds;
props->max_sge_rd = I40IW_MAX_SGE_RD;
props->max_qp_rd_atom = I40IW_MAX_IRD_SIZE;
props->max_qp_init_rd_atom = props->max_qp_rd_atom;
@@ -254,7 +255,6 @@ static void i40iw_alloc_push_page(struct i40iw_device *iwdev, struct i40iw_sc_qp
{
struct i40iw_cqp_request *cqp_request;
struct cqp_commands_info *cqp_info;
- struct i40iw_sc_dev *dev = &iwdev->sc_dev;
enum i40iw_status_code status;
if (qp->push_idx != I40IW_INVALID_PUSH_PAGE_INDEX)
@@ -270,7 +270,7 @@ static void i40iw_alloc_push_page(struct i40iw_device *iwdev, struct i40iw_sc_qp
cqp_info->cqp_cmd = OP_MANAGE_PUSH_PAGE;
cqp_info->post_sq = 1;
- cqp_info->in.u.manage_push_page.info.qs_handle = dev->qs_handle;
+ cqp_info->in.u.manage_push_page.info.qs_handle = qp->qs_handle;
cqp_info->in.u.manage_push_page.info.free_page = 0;
cqp_info->in.u.manage_push_page.cqp = &iwdev->cqp.sc_cqp;
cqp_info->in.u.manage_push_page.scratch = (uintptr_t)cqp_request;
@@ -292,7 +292,6 @@ static void i40iw_dealloc_push_page(struct i40iw_device *iwdev, struct i40iw_sc_
{
struct i40iw_cqp_request *cqp_request;
struct cqp_commands_info *cqp_info;
- struct i40iw_sc_dev *dev = &iwdev->sc_dev;
enum i40iw_status_code status;
if (qp->push_idx == I40IW_INVALID_PUSH_PAGE_INDEX)
@@ -307,7 +306,7 @@ static void i40iw_dealloc_push_page(struct i40iw_device *iwdev, struct i40iw_sc_
cqp_info->post_sq = 1;
cqp_info->in.u.manage_push_page.info.push_idx = qp->push_idx;
- cqp_info->in.u.manage_push_page.info.qs_handle = dev->qs_handle;
+ cqp_info->in.u.manage_push_page.info.qs_handle = qp->qs_handle;
cqp_info->in.u.manage_push_page.info.free_page = 1;
cqp_info->in.u.manage_push_page.cqp = &iwdev->cqp.sc_cqp;
cqp_info->in.u.manage_push_page.scratch = (uintptr_t)cqp_request;
@@ -337,6 +336,9 @@ static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
u32 pd_id = 0;
int err;
+ if (iwdev->closing)
+ return ERR_PTR(-ENODEV);
+
err = i40iw_alloc_resource(iwdev, iwdev->allocated_pds,
iwdev->max_pd, &pd_id, &iwdev->next_pd);
if (err) {
@@ -602,6 +604,9 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd,
struct i40iwarp_offload_info *iwarp_info;
unsigned long flags;
+ if (iwdev->closing)
+ return ERR_PTR(-ENODEV);
+
if (init_attr->create_flags)
return ERR_PTR(-EINVAL);
if (init_attr->cap.max_inline_data > I40IW_MAX_INLINE_DATA_SIZE)
@@ -610,11 +615,15 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd,
if (init_attr->cap.max_send_sge > I40IW_MAX_WQ_FRAGMENT_COUNT)
init_attr->cap.max_send_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
+ if (init_attr->cap.max_recv_sge > I40IW_MAX_WQ_FRAGMENT_COUNT)
+ init_attr->cap.max_recv_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
+
memset(&init_info, 0, sizeof(init_info));
sq_size = init_attr->cap.max_send_wr;
rq_size = init_attr->cap.max_recv_wr;
+ init_info.vsi = &iwdev->vsi;
init_info.qp_uk_init_info.sq_size = sq_size;
init_info.qp_uk_init_info.rq_size = rq_size;
init_info.qp_uk_init_info.max_sq_frag_cnt = init_attr->cap.max_send_sge;
@@ -774,6 +783,7 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd,
iwqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? 1 : 0;
iwdev->qp_table[qp_num] = iwqp;
i40iw_add_pdusecount(iwqp->iwpd);
+ i40iw_add_devusecount(iwdev);
if (ibpd->uobject && udata) {
memset(&uresp, 0, sizeof(uresp));
uresp.actual_sq_size = sq_size;
@@ -815,8 +825,9 @@ static int i40iw_query_qp(struct ib_qp *ibqp,
attr->qp_access_flags = 0;
attr->cap.max_send_wr = qp->qp_uk.sq_size;
attr->cap.max_recv_wr = qp->qp_uk.rq_size;
- attr->cap.max_recv_sge = 1;
attr->cap.max_inline_data = I40IW_MAX_INLINE_DATA_SIZE;
+ attr->cap.max_send_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
+ attr->cap.max_recv_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
init_attr->event_handler = iwqp->ibqp.event_handler;
init_attr->qp_context = iwqp->ibqp.qp_context;
init_attr->send_cq = iwqp->ibqp.send_cq;
@@ -884,6 +895,11 @@ int i40iw_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
spin_lock_irqsave(&iwqp->lock, flags);
if (attr_mask & IB_QP_STATE) {
+ if (iwdev->closing && attr->qp_state != IB_QPS_ERR) {
+ err = -EINVAL;
+ goto exit;
+ }
+
switch (attr->qp_state) {
case IB_QPS_INIT:
case IB_QPS_RTR:
@@ -944,7 +960,7 @@ int i40iw_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto exit;
}
if (iwqp->sc_qp.term_flags)
- del_timer(&iwqp->terminate_timer);
+ i40iw_terminate_del_timer(&iwqp->sc_qp);
info.next_iwarp_state = I40IW_QP_STATE_ERROR;
if ((iwqp->hw_tcp_state > I40IW_TCP_STATE_CLOSED) &&
iwdev->iw_status &&
@@ -1037,11 +1053,11 @@ static void cq_free_resources(struct i40iw_device *iwdev, struct i40iw_cq *iwcq)
}
/**
- * cq_wq_destroy - send cq destroy cqp
+ * i40iw_cq_wq_destroy - send cq destroy cqp
* @iwdev: iwarp device
* @cq: hardware control cq
*/
-static void cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq)
+void i40iw_cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq)
{
enum i40iw_status_code status;
struct i40iw_cqp_request *cqp_request;
@@ -1080,9 +1096,10 @@ static int i40iw_destroy_cq(struct ib_cq *ib_cq)
iwcq = to_iwcq(ib_cq);
iwdev = to_iwdev(ib_cq->device);
cq = &iwcq->sc_cq;
- cq_wq_destroy(iwdev, cq);
+ i40iw_cq_wq_destroy(iwdev, cq);
cq_free_resources(iwdev, iwcq);
kfree(iwcq);
+ i40iw_rem_devusecount(iwdev);
return 0;
}
@@ -1113,6 +1130,9 @@ static struct ib_cq *i40iw_create_cq(struct ib_device *ibdev,
int err_code;
int entries = attr->cqe;
+ if (iwdev->closing)
+ return ERR_PTR(-ENODEV);
+
if (entries > iwdev->max_cqe)
return ERR_PTR(-EINVAL);
@@ -1137,7 +1157,8 @@ static struct ib_cq *i40iw_create_cq(struct ib_device *ibdev,
ukinfo->cq_id = cq_num;
iwcq->ibcq.cqe = info.cq_uk_init_info.cq_size;
info.ceqe_mask = 0;
- info.ceq_id = 0;
+ if (attr->comp_vector < iwdev->ceqs_count)
+ info.ceq_id = attr->comp_vector;
info.ceq_id_valid = true;
info.ceqe_mask = 1;
info.type = I40IW_CQ_TYPE_IWARP;
@@ -1229,10 +1250,11 @@ static struct ib_cq *i40iw_create_cq(struct ib_device *ibdev,
}
}
+ i40iw_add_devusecount(iwdev);
return (struct ib_cq *)iwcq;
cq_destroy:
- cq_wq_destroy(iwdev, cq);
+ i40iw_cq_wq_destroy(iwdev, cq);
cq_free_resources:
cq_free_resources(iwdev, iwcq);
error:
@@ -1266,6 +1288,7 @@ static void i40iw_free_stag(struct i40iw_device *iwdev, u32 stag)
stag_idx = (stag & iwdev->mr_stagmask) >> I40IW_CQPSQ_STAG_IDX_SHIFT;
i40iw_free_resource(iwdev, iwdev->allocated_mrs, stag_idx);
+ i40iw_rem_devusecount(iwdev);
}
/**
@@ -1296,19 +1319,18 @@ static u32 i40iw_create_stag(struct i40iw_device *iwdev)
stag = stag_index << I40IW_CQPSQ_STAG_IDX_SHIFT;
stag |= driver_key;
stag += (u32)consumer_key;
+ i40iw_add_devusecount(iwdev);
}
return stag;
}
/**
* i40iw_next_pbl_addr - Get next pbl address
- * @palloc: Poiner to allocated pbles
* @pbl: pointer to a pble
* @pinfo: info pointer
* @idx: index
*/
-static inline u64 *i40iw_next_pbl_addr(struct i40iw_pble_alloc *palloc,
- u64 *pbl,
+static inline u64 *i40iw_next_pbl_addr(u64 *pbl,
struct i40iw_pble_info **pinfo,
u32 *idx)
{
@@ -1336,9 +1358,11 @@ static void i40iw_copy_user_pgaddrs(struct i40iw_mr *iwmr,
struct i40iw_pble_alloc *palloc = &iwpbl->pble_alloc;
struct i40iw_pble_info *pinfo;
struct scatterlist *sg;
+ u64 pg_addr = 0;
u32 idx = 0;
pinfo = (level == I40IW_LEVEL_1) ? NULL : palloc->level2.leaf;
+
pg_shift = ffs(region->page_size) - 1;
for_each_sg(region->sg_head.sgl, sg, region->nmap, entry) {
chunk_pages = sg_dma_len(sg) >> pg_shift;
@@ -1346,17 +1370,96 @@ static void i40iw_copy_user_pgaddrs(struct i40iw_mr *iwmr,
!iwpbl->qp_mr.sq_page)
iwpbl->qp_mr.sq_page = sg_page(sg);
for (i = 0; i < chunk_pages; i++) {
- *pbl = cpu_to_le64(sg_dma_address(sg) + region->page_size * i);
- pbl = i40iw_next_pbl_addr(palloc, pbl, &pinfo, &idx);
+ pg_addr = sg_dma_address(sg) + region->page_size * i;
+
+ if ((entry + i) == 0)
+ *pbl = cpu_to_le64(pg_addr & iwmr->page_msk);
+ else if (!(pg_addr & ~iwmr->page_msk))
+ *pbl = cpu_to_le64(pg_addr);
+ else
+ continue;
+ pbl = i40iw_next_pbl_addr(pbl, &pinfo, &idx);
+ }
+ }
+}
+
+/**
+ * i40iw_set_hugetlb_params - set MR pg size and mask to huge pg values.
+ * @addr: virtual address
+ * @iwmr: mr pointer for this memory registration
+ */
+static void i40iw_set_hugetlb_values(u64 addr, struct i40iw_mr *iwmr)
+{
+ struct vm_area_struct *vma;
+ struct hstate *h;
+
+ vma = find_vma(current->mm, addr);
+ if (vma && is_vm_hugetlb_page(vma)) {
+ h = hstate_vma(vma);
+ if (huge_page_size(h) == 0x200000) {
+ iwmr->page_size = huge_page_size(h);
+ iwmr->page_msk = huge_page_mask(h);
}
}
}
/**
+ * i40iw_check_mem_contiguous - check if pbls stored in arr are contiguous
+ * @arr: lvl1 pbl array
+ * @npages: page count
+ * pg_size: page size
+ *
+ */
+static bool i40iw_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+{
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+ if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+ return true;
+}
+
+/**
+ * i40iw_check_mr_contiguous - check if MR is physically contiguous
+ * @palloc: pbl allocation struct
+ * pg_size: page size
+ */
+static bool i40iw_check_mr_contiguous(struct i40iw_pble_alloc *palloc, u32 pg_size)
+{
+ struct i40iw_pble_level2 *lvl2 = &palloc->level2;
+ struct i40iw_pble_info *leaf = lvl2->leaf;
+ u64 *arr = NULL;
+ u64 *start_addr = NULL;
+ int i;
+ bool ret;
+
+ if (palloc->level == I40IW_LEVEL_1) {
+ arr = (u64 *)palloc->level1.addr;
+ ret = i40iw_check_mem_contiguous(arr, palloc->total_cnt, pg_size);
+ return ret;
+ }
+
+ start_addr = (u64 *)leaf->addr;
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = (u64 *)leaf->addr;
+ if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = i40iw_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+ return false;
+ }
+
+ return true;
+}
+
+/**
* i40iw_setup_pbles - copy user pg address to pble's
* @iwdev: iwarp device
* @iwmr: mr pointer for this memory registration
- * @use_pbles: flag if to use pble's or memory (level 0)
+ * @use_pbles: flag if to use pble's
*/
static int i40iw_setup_pbles(struct i40iw_device *iwdev,
struct i40iw_mr *iwmr,
@@ -1369,9 +1472,6 @@ static int i40iw_setup_pbles(struct i40iw_device *iwdev,
enum i40iw_status_code status;
enum i40iw_pble_level level = I40IW_LEVEL_1;
- if (!use_pbles && (iwmr->page_cnt > MAX_SAVE_PAGE_ADDRS))
- return -ENOMEM;
-
if (use_pbles) {
mutex_lock(&iwdev->pbl_mutex);
status = i40iw_get_pble(&iwdev->sc_dev, iwdev->pble_rsrc, palloc, iwmr->page_cnt);
@@ -1388,6 +1488,10 @@ static int i40iw_setup_pbles(struct i40iw_device *iwdev,
}
i40iw_copy_user_pgaddrs(iwmr, pbl, level);
+
+ if (use_pbles)
+ iwmr->pgaddrmem[0] = *pbl;
+
return 0;
}
@@ -1409,14 +1513,18 @@ static int i40iw_handle_q_mem(struct i40iw_device *iwdev,
struct i40iw_cq_mr *cqmr = &iwpbl->cq_mr;
struct i40iw_hmc_pble *hmc_p;
u64 *arr = iwmr->pgaddrmem;
+ u32 pg_size;
int err;
int total;
+ bool ret = true;
total = req->sq_pages + req->rq_pages + req->cq_pages;
+ pg_size = iwmr->page_size;
err = i40iw_setup_pbles(iwdev, iwmr, use_pbles);
if (err)
return err;
+
if (use_pbles && (palloc->level != I40IW_LEVEL_1)) {
i40iw_free_pble(iwdev->pble_rsrc, palloc);
iwpbl->pbl_allocated = false;
@@ -1425,26 +1533,44 @@ static int i40iw_handle_q_mem(struct i40iw_device *iwdev,
if (use_pbles)
arr = (u64 *)palloc->level1.addr;
- if (req->reg_type == IW_MEMREG_TYPE_QP) {
+
+ if (iwmr->type == IW_MEMREG_TYPE_QP) {
hmc_p = &qpmr->sq_pbl;
qpmr->shadow = (dma_addr_t)arr[total];
+
if (use_pbles) {
+ ret = i40iw_check_mem_contiguous(arr, req->sq_pages, pg_size);
+ if (ret)
+ ret = i40iw_check_mem_contiguous(&arr[req->sq_pages], req->rq_pages, pg_size);
+ }
+
+ if (!ret) {
hmc_p->idx = palloc->level1.idx;
hmc_p = &qpmr->rq_pbl;
hmc_p->idx = palloc->level1.idx + req->sq_pages;
} else {
hmc_p->addr = arr[0];
hmc_p = &qpmr->rq_pbl;
- hmc_p->addr = arr[1];
+ hmc_p->addr = arr[req->sq_pages];
}
} else { /* CQ */
hmc_p = &cqmr->cq_pbl;
cqmr->shadow = (dma_addr_t)arr[total];
+
if (use_pbles)
+ ret = i40iw_check_mem_contiguous(arr, req->cq_pages, pg_size);
+
+ if (!ret)
hmc_p->idx = palloc->level1.idx;
else
hmc_p->addr = arr[0];
}
+
+ if (use_pbles && ret) {
+ i40iw_free_pble(iwdev->pble_rsrc, palloc);
+ iwpbl->pbl_allocated = false;
+ }
+
return err;
}
@@ -1642,8 +1768,9 @@ static int i40iw_hwreg_mr(struct i40iw_device *iwdev,
stag_info->access_rights = access;
stag_info->pd_id = iwpd->sc_pd.pd_id;
stag_info->addr_type = I40IW_ADDR_TYPE_VA_BASED;
+ stag_info->page_size = iwmr->page_size;
- if (iwmr->page_cnt > 1) {
+ if (iwpbl->pbl_allocated) {
if (palloc->level == I40IW_LEVEL_1) {
stag_info->first_pm_pbl_index = palloc->level1.idx;
stag_info->chunk_size = 1;
@@ -1699,6 +1826,11 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
bool use_pbles = false;
unsigned long flags;
int err = -ENOSYS;
+ int ret;
+ int pg_shift;
+
+ if (iwdev->closing)
+ return ERR_PTR(-ENODEV);
if (length > I40IW_MAX_MR_SIZE)
return ERR_PTR(-EINVAL);
@@ -1723,9 +1855,17 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
iwmr->ibmr.pd = pd;
iwmr->ibmr.device = pd->device;
ucontext = to_ucontext(pd->uobject->context);
- region_length = region->length + (start & 0xfff);
- pbl_depth = region_length >> 12;
- pbl_depth += (region_length & (4096 - 1)) ? 1 : 0;
+
+ iwmr->page_size = region->page_size;
+ iwmr->page_msk = PAGE_MASK;
+
+ if (region->hugetlb && (req.reg_type == IW_MEMREG_TYPE_MEM))
+ i40iw_set_hugetlb_values(start, iwmr);
+
+ region_length = region->length + (start & (iwmr->page_size - 1));
+ pg_shift = ffs(iwmr->page_size) - 1;
+ pbl_depth = region_length >> pg_shift;
+ pbl_depth += (region_length & (iwmr->page_size - 1)) ? 1 : 0;
iwmr->length = region->length;
iwpbl->user_base = virt;
@@ -1755,13 +1895,21 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
spin_unlock_irqrestore(&ucontext->cq_reg_mem_list_lock, flags);
break;
case IW_MEMREG_TYPE_MEM:
+ use_pbles = (iwmr->page_cnt != 1);
access = I40IW_ACCESS_FLAGS_LOCALREAD;
- use_pbles = (iwmr->page_cnt != 1);
err = i40iw_setup_pbles(iwdev, iwmr, use_pbles);
if (err)
goto error;
+ if (use_pbles) {
+ ret = i40iw_check_mr_contiguous(palloc, iwmr->page_size);
+ if (ret) {
+ i40iw_free_pble(iwdev->pble_rsrc, palloc);
+ iwpbl->pbl_allocated = false;
+ }
+ }
+
access |= i40iw_get_user_access(acc);
stag = i40iw_create_stag(iwdev);
if (!stag) {
@@ -1778,6 +1926,7 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
i40iw_free_stag(iwdev, stag);
goto error;
}
+
break;
default:
goto error;
@@ -1789,7 +1938,7 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
return &iwmr->ibmr;
error:
- if (palloc->level != I40IW_LEVEL_0)
+ if (palloc->level != I40IW_LEVEL_0 && iwpbl->pbl_allocated)
i40iw_free_pble(iwdev->pble_rsrc, palloc);
ib_umem_release(region);
kfree(iwmr);
@@ -2142,7 +2291,6 @@ static int i40iw_post_send(struct ib_qp *ibqp,
case IB_WR_REG_MR:
{
struct i40iw_mr *iwmr = to_iwmr(reg_wr(ib_wr)->mr);
- int page_shift = ilog2(reg_wr(ib_wr)->mr->page_size);
int flags = reg_wr(ib_wr)->access;
struct i40iw_pble_alloc *palloc = &iwmr->iwpbl.pble_alloc;
struct i40iw_sc_dev *dev = &iwqp->iwdev->sc_dev;
@@ -2153,6 +2301,7 @@ static int i40iw_post_send(struct ib_qp *ibqp,
info.access_rights |= i40iw_get_user_access(flags);
info.stag_key = reg_wr(ib_wr)->key & 0xff;
info.stag_idx = reg_wr(ib_wr)->key >> 8;
+ info.page_size = reg_wr(ib_wr)->mr->page_size;
info.wr_id = ib_wr->wr_id;
info.addr_type = I40IW_ADDR_TYPE_VA_BASED;
@@ -2166,9 +2315,6 @@ static int i40iw_post_send(struct ib_qp *ibqp,
if (iwmr->npages > I40IW_MIN_PAGES_PER_FMR)
info.chunk_size = 1;
- if (page_shift == 21)
- info.page_size = 1; /* 2M page */
-
ret = dev->iw_priv_qp_ops->iw_mr_fast_register(&iwqp->sc_qp, &info, true);
if (ret)
err = -ENOMEM;
@@ -2487,21 +2633,17 @@ static int i40iw_get_hw_stats(struct ib_device *ibdev,
{
struct i40iw_device *iwdev = to_iwdev(ibdev);
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
- struct i40iw_dev_pestat *devstat = &dev->dev_pestat;
+ struct i40iw_vsi_pestat *devstat = iwdev->vsi.pestat;
struct i40iw_dev_hw_stats *hw_stats = &devstat->hw_stats;
- unsigned long flags;
if (dev->is_pf) {
- spin_lock_irqsave(&devstat->stats_lock, flags);
- devstat->ops.iw_hw_stat_read_all(devstat,
- &devstat->hw_stats);
- spin_unlock_irqrestore(&devstat->stats_lock, flags);
+ i40iw_hw_stats_read_all(devstat, &devstat->hw_stats);
} else {
if (i40iw_vchnl_vf_get_pe_stats(dev, &devstat->hw_stats))
return -ENOSYS;
}
- memcpy(&stats->value[0], &hw_stats, sizeof(*hw_stats));
+ memcpy(&stats->value[0], hw_stats, sizeof(*hw_stats));
return stats->num_counters;
}
@@ -2562,7 +2704,9 @@ static int i40iw_query_pkey(struct ib_device *ibdev,
* @ah_attr: address handle attributes
*/
static struct ib_ah *i40iw_create_ah(struct ib_pd *ibpd,
- struct ib_ah_attr *attr)
+ struct ib_ah_attr *attr,
+ struct ib_udata *udata)
+
{
return ERR_PTR(-ENOSYS);
}
@@ -2621,7 +2765,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
(1ull << IB_USER_VERBS_CMD_POST_RECV) |
(1ull << IB_USER_VERBS_CMD_POST_SEND);
iwibdev->ibdev.phys_port_cnt = 1;
- iwibdev->ibdev.num_comp_vectors = 1;
+ iwibdev->ibdev.num_comp_vectors = iwdev->ceqs_count;
iwibdev->ibdev.dma_device = &pcidev->dev;
iwibdev->ibdev.dev.parent = &pcidev->dev;
iwibdev->ibdev.query_port = i40iw_query_port;
@@ -2654,7 +2798,6 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
iwibdev->ibdev.iwcm = kzalloc(sizeof(*iwibdev->ibdev.iwcm), GFP_KERNEL);
if (!iwibdev->ibdev.iwcm) {
ib_dealloc_device(&iwibdev->ibdev);
- i40iw_pr_err("iwcm == NULL\n");
return NULL;
}
@@ -2719,6 +2862,9 @@ void i40iw_destroy_rdma_device(struct i40iw_ib_device *iwibdev)
i40iw_unregister_rdma_device(iwibdev);
kfree(iwibdev->ibdev.iwcm);
iwibdev->ibdev.iwcm = NULL;
+ wait_event_timeout(iwibdev->iwdev->close_wq,
+ !atomic64_read(&iwibdev->iwdev->use_count),
+ I40IW_EVENT_TIMEOUT);
ib_dealloc_device(&iwibdev->ibdev);
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.h b/drivers/infiniband/hw/i40iw/i40iw_verbs.h
index 0069be8a5a38..6549c939500f 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.h
@@ -92,6 +92,8 @@ struct i40iw_mr {
struct ib_umem *region;
u16 type;
u32 page_cnt;
+ u32 page_size;
+ u64 page_msk;
u32 npages;
u32 stag;
u64 length;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c b/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c
index 3041003c94d2..f4d13683a403 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c
@@ -403,6 +403,19 @@ del_out:
}
/**
+ * i40iw_vf_init_pestat - Initialize stats for VF
+ * @devL pointer to the VF Device
+ * @stats: Statistics structure pointer
+ * @index: Stats index
+ */
+static void i40iw_vf_init_pestat(struct i40iw_sc_dev *dev, struct i40iw_vsi_pestat *stats, u16 index)
+{
+ stats->hw = dev->hw;
+ i40iw_hw_stats_init(stats, (u8)index, false);
+ spin_lock_init(&stats->lock);
+}
+
+/**
* i40iw_vchnl_recv_pf - Receive PF virtual channel messages
* @dev: IWARP device pointer
* @vf_id: Virtual function ID associated with the message
@@ -421,9 +434,8 @@ enum i40iw_status_code i40iw_vchnl_recv_pf(struct i40iw_sc_dev *dev,
u16 first_avail_iw_vf = I40IW_MAX_PE_ENABLED_VF_COUNT;
struct i40iw_virt_mem vf_dev_mem;
struct i40iw_virtchnl_work_info work_info;
- struct i40iw_dev_pestat *devstat;
+ struct i40iw_vsi_pestat *stats;
enum i40iw_status_code ret_code;
- unsigned long flags;
if (!dev || !msg || !len)
return I40IW_ERR_PARAM;
@@ -496,14 +508,7 @@ enum i40iw_status_code i40iw_vchnl_recv_pf(struct i40iw_sc_dev *dev,
i40iw_debug(dev, I40IW_DEBUG_VIRT,
"VF%u error CQP HMC Function operation.\n",
vf_id);
- ret_code = i40iw_device_init_pestat(&vf_dev->dev_pestat);
- if (ret_code)
- i40iw_debug(dev, I40IW_DEBUG_VIRT,
- "VF%u - i40iw_device_init_pestat failed\n",
- vf_id);
- vf_dev->dev_pestat.ops.iw_hw_stat_init(&vf_dev->dev_pestat,
- (u8)vf_dev->pmf_index,
- dev->hw, false);
+ i40iw_vf_init_pestat(dev, &vf_dev->pestat, vf_dev->pmf_index);
vf_dev->stats_initialized = true;
} else {
if (vf_dev) {
@@ -534,12 +539,10 @@ enum i40iw_status_code i40iw_vchnl_recv_pf(struct i40iw_sc_dev *dev,
case I40IW_VCHNL_OP_GET_STATS:
if (!vf_dev)
return I40IW_ERR_BAD_PTR;
- devstat = &vf_dev->dev_pestat;
- spin_lock_irqsave(&dev->dev_pestat.stats_lock, flags);
- devstat->ops.iw_hw_stat_read_all(devstat, &devstat->hw_stats);
- spin_unlock_irqrestore(&dev->dev_pestat.stats_lock, flags);
+ stats = &vf_dev->pestat;
+ i40iw_hw_stats_read_all(stats, &stats->hw_stats);
vf_dev->msg_count--;
- vchnl_pf_send_get_pe_stats_resp(dev, vf_id, vchnl_msg, &devstat->hw_stats);
+ vchnl_pf_send_get_pe_stats_resp(dev, vf_id, vchnl_msg, &stats->hw_stats);
break;
default:
i40iw_debug(dev, I40IW_DEBUG_VIRT,
diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index b9bf0759f10a..077c33d2dc75 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -114,7 +114,9 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
!(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support))
--ah->av.eth.stat_rate;
}
-
+ ah->av.eth.sl_tclass_flowlabel |=
+ cpu_to_be32((ah_attr->grh.traffic_class << 20) |
+ ah_attr->grh.flow_label);
/*
* HW requires multicast LID so we just choose one.
*/
@@ -122,12 +124,14 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
ah->av.ib.dlid = cpu_to_be16(0xc000);
memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16);
- ah->av.eth.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 29);
+ ah->av.eth.sl_tclass_flowlabel |= cpu_to_be32(ah_attr->sl << 29);
return &ah->ibah;
}
-struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
+struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
+
{
struct mlx4_ib_ah *ah;
struct ib_ah *ret;
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c
index 5e9939045852..06020c54db20 100644
--- a/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ b/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -755,10 +755,8 @@ static void alias_guid_work(struct work_struct *work)
struct mlx4_ib_dev *dev = container_of(ib_sriov, struct mlx4_ib_dev, sriov);
rec = kzalloc(sizeof *rec, GFP_KERNEL);
- if (!rec) {
- pr_err("alias_guid_work: No Memory\n");
+ if (!rec)
return;
- }
pr_debug("starting [port: %d]...\n", sriov_alias_port->port + 1);
ret = get_next_record_to_update(dev, sriov_alias_port->port, rec);
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index 39a488889fc7..d64845335e87 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -247,10 +247,8 @@ id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id)
struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov;
ent = kmalloc(sizeof (struct id_map_entry), GFP_KERNEL);
- if (!ent) {
- mlx4_ib_warn(ibdev, "Couldn't allocate id cache entry - out of memory\n");
+ if (!ent)
return ERR_PTR(-ENOMEM);
- }
ent->sl_cm_id = sl_cm_id;
ent->slave_id = slave_id;
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 1672907ff219..db564ccc0f92 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -39,6 +39,8 @@
#include <linux/mlx4/cmd.h>
#include <linux/gfp.h>
#include <rdma/ib_pma.h>
+#include <linux/ip.h>
+#include <net/ipv6.h>
#include <linux/mlx4/driver.h>
#include "mlx4_ib.h"
@@ -480,6 +482,23 @@ static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave,
return -EINVAL;
}
+static int get_gids_from_l3_hdr(struct ib_grh *grh, union ib_gid *sgid,
+ union ib_gid *dgid)
+{
+ int version = ib_get_rdma_header_version((const union rdma_network_hdr *)grh);
+ enum rdma_network_type net_type;
+
+ if (version == 4)
+ net_type = RDMA_NETWORK_IPV4;
+ else if (version == 6)
+ net_type = RDMA_NETWORK_IPV6;
+ else
+ return -EINVAL;
+
+ return ib_get_gids_from_rdma_hdr((union rdma_network_hdr *)grh, net_type,
+ sgid, dgid);
+}
+
int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
enum ib_qp_type dest_qpt, struct ib_wc *wc,
struct ib_grh *grh, struct ib_mad *mad)
@@ -538,7 +557,10 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
memset(&attr, 0, sizeof attr);
attr.port_num = port;
if (is_eth) {
- memcpy(&attr.grh.dgid.raw[0], &grh->dgid.raw[0], 16);
+ union ib_gid sgid;
+
+ if (get_gids_from_l3_hdr(grh, &sgid, &attr.grh.dgid))
+ return -EINVAL;
attr.ah_flags = IB_AH_GRH;
}
ah = ib_create_ah(tun_ctx->pd, &attr);
@@ -651,6 +673,11 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port,
is_eth = 1;
if (is_eth) {
+ union ib_gid dgid;
+ union ib_gid sgid;
+
+ if (get_gids_from_l3_hdr(grh, &sgid, &dgid))
+ return -EINVAL;
if (!(wc->wc_flags & IB_WC_GRH)) {
mlx4_ib_warn(ibdev, "RoCE grh not present.\n");
return -EINVAL;
@@ -659,10 +686,10 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port,
mlx4_ib_warn(ibdev, "RoCE mgmt class is not CM\n");
return -EINVAL;
}
- err = mlx4_get_slave_from_roce_gid(dev->dev, port, grh->dgid.raw, &slave);
+ err = mlx4_get_slave_from_roce_gid(dev->dev, port, dgid.raw, &slave);
if (err && mlx4_is_mf_bonded(dev->dev)) {
other_port = (port == 1) ? 2 : 1;
- err = mlx4_get_slave_from_roce_gid(dev->dev, other_port, grh->dgid.raw, &slave);
+ err = mlx4_get_slave_from_roce_gid(dev->dev, other_port, dgid.raw, &slave);
if (!err) {
port = other_port;
pr_debug("resolved slave %d from gid %pI6 wire port %d other %d\n",
@@ -702,10 +729,18 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port,
/* If a grh is present, we demux according to it */
if (wc->wc_flags & IB_WC_GRH) {
- slave = mlx4_ib_find_real_gid(ibdev, port, grh->dgid.global.interface_id);
- if (slave < 0) {
- mlx4_ib_warn(ibdev, "failed matching grh\n");
- return -ENOENT;
+ if (grh->dgid.global.interface_id ==
+ cpu_to_be64(IB_SA_WELL_KNOWN_GUID) &&
+ grh->dgid.global.subnet_prefix == cpu_to_be64(
+ atomic64_read(&dev->sriov.demux[port - 1].subnet_prefix))) {
+ slave = 0;
+ } else {
+ slave = mlx4_ib_find_real_gid(ibdev, port,
+ grh->dgid.global.interface_id);
+ if (slave < 0) {
+ mlx4_ib_warn(ibdev, "failed matching grh\n");
+ return -ENOENT;
+ }
}
}
/* Class-specific handling */
@@ -1102,10 +1137,8 @@ static void handle_slaves_guid_change(struct mlx4_ib_dev *dev, u8 port_num,
in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
- if (!in_mad || !out_mad) {
- mlx4_ib_warn(&dev->ib_dev, "failed to allocate memory for guid info mads\n");
+ if (!in_mad || !out_mad)
goto out;
- }
guid_tbl_blk_num *= 4;
@@ -1916,11 +1949,8 @@ static int alloc_pv_object(struct mlx4_ib_dev *dev, int slave, int port,
*ret_ctx = NULL;
ctx = kzalloc(sizeof (struct mlx4_ib_demux_pv_ctx), GFP_KERNEL);
- if (!ctx) {
- pr_err("failed allocating pv resource context "
- "for port %d, slave %d\n", port, slave);
+ if (!ctx)
return -ENOMEM;
- }
ctx->ib_dev = &dev->ib_dev;
ctx->port = port;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index b597e8227591..c8413fc120e6 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -430,7 +430,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
struct mlx4_ib_dev *dev = to_mdev(ibdev);
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
- int err = -ENOMEM;
+ int err;
int have_ib_ports;
struct mlx4_uverbs_ex_query_device cmd;
struct mlx4_uverbs_ex_query_device_resp resp = {.comp_mask = 0};
@@ -455,6 +455,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
sizeof(resp.response_length);
in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+ err = -ENOMEM;
if (!in_mad || !out_mad)
goto out;
@@ -547,6 +548,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
props->max_map_per_fmr = dev->dev->caps.max_fmr_maps;
props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL;
props->timestamp_mask = 0xFFFFFFFFFFFFULL;
+ props->max_ah = INT_MAX;
if (!mlx4_is_slave(dev->dev))
err = mlx4_get_internal_clock_params(dev->dev, &clock_params);
@@ -697,9 +699,11 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
if (err)
goto out;
- props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ?
- IB_WIDTH_4X : IB_WIDTH_1X;
- props->active_speed = IB_SPEED_QDR;
+ props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ||
+ (((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ?
+ IB_WIDTH_4X : IB_WIDTH_1X;
+ props->active_speed = (((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ?
+ IB_SPEED_FDR : IB_SPEED_QDR;
props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS;
props->gid_tbl_len = mdev->dev->caps.gid_table_len[port];
props->max_msg_sz = mdev->dev->caps.max_msg_sz;
@@ -2814,20 +2818,22 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
kmalloc(BITS_TO_LONGS(ibdev->steer_qpn_count) *
sizeof(long),
GFP_KERNEL);
- if (!ibdev->ib_uc_qpns_bitmap) {
- dev_err(&dev->persist->pdev->dev,
- "bit map alloc failed\n");
+ if (!ibdev->ib_uc_qpns_bitmap)
goto err_steer_qp_release;
- }
- bitmap_zero(ibdev->ib_uc_qpns_bitmap, ibdev->steer_qpn_count);
-
- err = mlx4_FLOW_STEERING_IB_UC_QP_RANGE(
- dev, ibdev->steer_qpn_base,
- ibdev->steer_qpn_base +
- ibdev->steer_qpn_count - 1);
- if (err)
- goto err_steer_free_bitmap;
+ if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_DMFS_IPOIB) {
+ bitmap_zero(ibdev->ib_uc_qpns_bitmap,
+ ibdev->steer_qpn_count);
+ err = mlx4_FLOW_STEERING_IB_UC_QP_RANGE(
+ dev, ibdev->steer_qpn_base,
+ ibdev->steer_qpn_base +
+ ibdev->steer_qpn_count - 1);
+ if (err)
+ goto err_steer_free_bitmap;
+ } else {
+ bitmap_fill(ibdev->ib_uc_qpns_bitmap,
+ ibdev->steer_qpn_count);
+ }
}
for (j = 1; j <= ibdev->dev->caps.num_ports; j++)
@@ -3055,15 +3061,12 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init)
first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports);
dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC);
- if (!dm) {
- pr_err("failed to allocate memory for tunneling qp update\n");
+ if (!dm)
return;
- }
for (i = 0; i < ports; i++) {
dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC);
if (!dm[i]) {
- pr_err("failed to allocate memory for tunneling qp update work struct\n");
while (--i >= 0)
kfree(dm[i]);
goto out;
@@ -3223,8 +3226,6 @@ void mlx4_sched_ib_sl2vl_update_work(struct mlx4_ib_dev *ibdev,
ew->port = port;
ew->ib_dev = ibdev;
queue_work(wq, &ew->work);
- } else {
- pr_err("failed to allocate memory for sl2vl update work\n");
}
}
@@ -3284,10 +3285,8 @@ static void mlx4_ib_event(struct mlx4_dev *dev, void *ibdev_ptr,
case MLX4_DEV_EVENT_PORT_MGMT_CHANGE:
ew = kmalloc(sizeof *ew, GFP_ATOMIC);
- if (!ew) {
- pr_err("failed to allocate memory for events work\n");
+ if (!ew)
break;
- }
INIT_WORK(&ew->work, handle_port_mgmt_change_event);
memcpy(&ew->ib_eqe, eqe, sizeof *eqe);
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c
index a21d37f02f35..e010fe459e67 100644
--- a/drivers/infiniband/hw/mlx4/mcg.c
+++ b/drivers/infiniband/hw/mlx4/mcg.c
@@ -1142,7 +1142,6 @@ void mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy_wq)
work = kmalloc(sizeof *work, GFP_KERNEL);
if (!work) {
ctx->flushing = 0;
- mcg_warn("failed allocating work for cleanup\n");
return;
}
@@ -1202,10 +1201,8 @@ static int push_deleteing_req(struct mcast_group *group, int slave)
return 0;
req = kzalloc(sizeof *req, GFP_KERNEL);
- if (!req) {
- mcg_warn_group(group, "failed allocation - may leave stall groups\n");
+ if (!req)
return -ENOMEM;
- }
if (!list_empty(&group->func[slave].pending)) {
pend_req = list_entry(group->func[slave].pending.prev, struct mcast_req, group_list);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 35141f451e5c..7f3d976d81ed 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -742,7 +742,8 @@ int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
-struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
+struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata);
int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
int mlx4_ib_destroy_ah(struct ib_ah *ah);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 570bc866b1d6..c068add8838b 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -644,7 +644,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
int qpn;
int err;
struct ib_qp_cap backup_cap;
- struct mlx4_ib_sqp *sqp;
+ struct mlx4_ib_sqp *sqp = NULL;
struct mlx4_ib_qp *qp;
enum mlx4_ib_qp_type qp_type = (enum mlx4_ib_qp_type) init_attr->qp_type;
struct mlx4_ib_cq *mcq;
@@ -933,7 +933,9 @@ err_db:
mlx4_db_free(dev->dev, &qp->db);
err:
- if (!*caller_qp)
+ if (sqp)
+ kfree(sqp);
+ else if (!*caller_qp)
kfree(qp);
return err;
}
@@ -1280,7 +1282,8 @@ static int _mlx4_ib_destroy_qp(struct ib_qp *qp)
if (is_qp0(dev, mqp))
mlx4_CLOSE_PORT(dev->dev, mqp->port);
- if (dev->qp1_proxy[mqp->port - 1] == mqp) {
+ if (mqp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI &&
+ dev->qp1_proxy[mqp->port - 1] == mqp) {
mutex_lock(&dev->qp1_proxy_lock[mqp->port - 1]);
dev->qp1_proxy[mqp->port - 1] = NULL;
mutex_unlock(&dev->qp1_proxy_lock[mqp->port - 1]);
@@ -1764,14 +1767,14 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
u8 port_num = mlx4_is_bonded(to_mdev(ibqp->device)->dev) ? 1 :
attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
union ib_gid gid;
- struct ib_gid_attr gid_attr;
+ struct ib_gid_attr gid_attr = {.gid_type = IB_GID_TYPE_IB};
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 (is_eth) {
+ if (is_eth && attr->ah_attr.ah_flags & IB_AH_GRH) {
int index = attr->ah_attr.grh.sgid_index;
status = ib_get_cached_gid(ibqp->device, port_num,
diff --git a/drivers/infiniband/hw/mlx5/ah.c b/drivers/infiniband/hw/mlx5/ah.c
index 745efa4cfc71..d090e96f6f01 100644
--- a/drivers/infiniband/hw/mlx5/ah.c
+++ b/drivers/infiniband/hw/mlx5/ah.c
@@ -64,7 +64,9 @@ static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev,
return &ah->ibah;
}
-struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
+struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
+
{
struct mlx5_ib_ah *ah;
struct mlx5_ib_dev *dev = to_mdev(pd->device);
@@ -75,6 +77,27 @@ struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
if (ll == IB_LINK_LAYER_ETHERNET && !(ah_attr->ah_flags & IB_AH_GRH))
return ERR_PTR(-EINVAL);
+ if (ll == IB_LINK_LAYER_ETHERNET && udata) {
+ int err;
+ struct mlx5_ib_create_ah_resp resp = {};
+ u32 min_resp_len = offsetof(typeof(resp), dmac) +
+ sizeof(resp.dmac);
+
+ if (udata->outlen < min_resp_len)
+ return ERR_PTR(-EINVAL);
+
+ resp.response_length = min_resp_len;
+
+ err = ib_resolve_eth_dmac(pd->device, ah_attr);
+ if (err)
+ return ERR_PTR(err);
+
+ memcpy(resp.dmac, ah_attr->dmac, ETH_ALEN);
+ err = ib_copy_to_udata(udata, &resp, resp.response_length);
+ if (err)
+ return ERR_PTR(err);
+ }
+
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index fcd04b881ec1..b3ef47c3ab73 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -731,7 +731,7 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
int entries, u32 **cqb,
int *cqe_size, int *index, int *inlen)
{
- struct mlx5_ib_create_cq ucmd;
+ struct mlx5_ib_create_cq ucmd = {};
size_t ucmdlen;
int page_shift;
__be64 *pas;
@@ -770,7 +770,7 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
if (err)
goto err_umem;
- mlx5_ib_cont_pages(cq->buf.umem, ucmd.buf_addr, &npages, &page_shift,
+ mlx5_ib_cont_pages(cq->buf.umem, ucmd.buf_addr, 0, &npages, &page_shift,
&ncont, NULL);
mlx5_ib_dbg(dev, "addr 0x%llx, size %u, npages %d, page_shift %d, ncont %d\n",
ucmd.buf_addr, entries * ucmd.cqe_size, npages, page_shift, ncont);
@@ -792,8 +792,36 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
*index = to_mucontext(context)->uuari.uars[0].index;
+ if (ucmd.cqe_comp_en == 1) {
+ if (unlikely((*cqe_size != 64) ||
+ !MLX5_CAP_GEN(dev->mdev, cqe_compression))) {
+ err = -EOPNOTSUPP;
+ mlx5_ib_warn(dev, "CQE compression is not supported for size %d!\n",
+ *cqe_size);
+ goto err_cqb;
+ }
+
+ if (unlikely(!ucmd.cqe_comp_res_format ||
+ !(ucmd.cqe_comp_res_format <
+ MLX5_IB_CQE_RES_RESERVED) ||
+ (ucmd.cqe_comp_res_format &
+ (ucmd.cqe_comp_res_format - 1)))) {
+ err = -EOPNOTSUPP;
+ mlx5_ib_warn(dev, "CQE compression res format %d is not supported!\n",
+ ucmd.cqe_comp_res_format);
+ goto err_cqb;
+ }
+
+ MLX5_SET(cqc, cqc, cqe_comp_en, 1);
+ MLX5_SET(cqc, cqc, mini_cqe_res_format,
+ ilog2(ucmd.cqe_comp_res_format));
+ }
+
return 0;
+err_cqb:
+ kfree(cqb);
+
err_db:
mlx5_ib_db_unmap_user(to_mucontext(context), &cq->db);
@@ -1124,7 +1152,7 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
return err;
}
- mlx5_ib_cont_pages(umem, ucmd.buf_addr, &npages, page_shift,
+ mlx5_ib_cont_pages(umem, ucmd.buf_addr, 0, &npages, page_shift,
npas, NULL);
cq->resize_umem = umem;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 2be65ddf56ba..d566f6738833 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -127,7 +127,7 @@ static int mlx5_netdev_event(struct notifier_block *this,
if ((upper == ndev || (!upper && ndev == ibdev->roce.netdev))
&& ibdev->ib_active) {
- struct ib_event ibev = {0};
+ struct ib_event ibev = { };
ibev.device = &ibdev->ib_dev;
ibev.event = (event == NETDEV_UP) ?
@@ -496,6 +496,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
struct mlx5_ib_dev *dev = to_mdev(ibdev);
struct mlx5_core_dev *mdev = dev->mdev;
int err = -ENOMEM;
+ int max_sq_desc;
int max_rq_sg;
int max_sq_sg;
u64 min_page_size = 1ull << MLX5_CAP_GEN(mdev, log_pg_sz);
@@ -618,9 +619,10 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz);
max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) /
sizeof(struct mlx5_wqe_data_seg);
- max_sq_sg = (MLX5_CAP_GEN(mdev, max_wqe_sz_sq) -
- sizeof(struct mlx5_wqe_ctrl_seg)) /
- sizeof(struct mlx5_wqe_data_seg);
+ max_sq_desc = min_t(int, MLX5_CAP_GEN(mdev, max_wqe_sz_sq), 512);
+ max_sq_sg = (max_sq_desc - sizeof(struct mlx5_wqe_ctrl_seg) -
+ sizeof(struct mlx5_wqe_raddr_seg)) /
+ sizeof(struct mlx5_wqe_data_seg);
props->max_sge = min(max_rq_sg, max_sq_sg);
props->max_sge_rd = MLX5_MAX_SGE_RD;
props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq);
@@ -643,6 +645,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
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->max_ah = INT_MAX;
props->hca_core_clock = MLX5_CAP_GEN(mdev, device_frequency_khz);
props->timestamp_mask = 0x7FFFFFFFFFFFFFFFULL;
@@ -669,6 +672,40 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
1 << MLX5_CAP_GEN(dev->mdev, log_max_rq);
}
+ if (field_avail(typeof(resp), mlx5_ib_support_multi_pkt_send_wqes,
+ uhw->outlen)) {
+ resp.mlx5_ib_support_multi_pkt_send_wqes =
+ MLX5_CAP_ETH(mdev, multi_pkt_send_wqe);
+ resp.response_length +=
+ sizeof(resp.mlx5_ib_support_multi_pkt_send_wqes);
+ }
+
+ if (field_avail(typeof(resp), reserved, uhw->outlen))
+ resp.response_length += sizeof(resp.reserved);
+
+ if (field_avail(typeof(resp), cqe_comp_caps, uhw->outlen)) {
+ resp.cqe_comp_caps.max_num =
+ MLX5_CAP_GEN(dev->mdev, cqe_compression) ?
+ MLX5_CAP_GEN(dev->mdev, cqe_compression_max_num) : 0;
+ resp.cqe_comp_caps.supported_format =
+ MLX5_IB_CQE_RES_FORMAT_HASH |
+ MLX5_IB_CQE_RES_FORMAT_CSUM;
+ resp.response_length += sizeof(resp.cqe_comp_caps);
+ }
+
+ if (field_avail(typeof(resp), packet_pacing_caps, uhw->outlen)) {
+ if (MLX5_CAP_QOS(mdev, packet_pacing) &&
+ MLX5_CAP_GEN(mdev, qos)) {
+ resp.packet_pacing_caps.qp_rate_limit_max =
+ MLX5_CAP_QOS(mdev, packet_pacing_max_rate);
+ resp.packet_pacing_caps.qp_rate_limit_min =
+ MLX5_CAP_QOS(mdev, packet_pacing_min_rate);
+ resp.packet_pacing_caps.supported_qpts |=
+ 1 << IB_QPT_RAW_PACKET;
+ }
+ resp.response_length += sizeof(resp.packet_pacing_caps);
+ }
+
if (uhw->outlen) {
err = ib_copy_to_udata(uhw, &resp, resp.response_length);
@@ -1093,7 +1130,8 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
resp.response_length += sizeof(resp.cqe_version);
if (field_avail(typeof(resp), cmds_supp_uhw, udata->outlen)) {
- resp.cmds_supp_uhw |= MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE;
+ resp.cmds_supp_uhw |= MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE |
+ MLX5_USER_CMDS_SUPP_UHW_CREATE_AH;
resp.response_length += sizeof(resp.cmds_supp_uhw);
}
@@ -1502,6 +1540,22 @@ static void set_proto(void *outer_c, void *outer_v, u8 mask, u8 val)
MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val);
}
+static void set_flow_label(void *misc_c, void *misc_v, u8 mask, u8 val,
+ bool inner)
+{
+ if (inner) {
+ MLX5_SET(fte_match_set_misc,
+ misc_c, inner_ipv6_flow_label, mask);
+ MLX5_SET(fte_match_set_misc,
+ misc_v, inner_ipv6_flow_label, val);
+ } else {
+ MLX5_SET(fte_match_set_misc,
+ misc_c, outer_ipv6_flow_label, mask);
+ MLX5_SET(fte_match_set_misc,
+ misc_v, outer_ipv6_flow_label, val);
+ }
+}
+
static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
{
MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_ecn, mask);
@@ -1515,6 +1569,7 @@ static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
#define LAST_IPV4_FIELD tos
#define LAST_IPV6_FIELD traffic_class
#define LAST_TCP_UDP_FIELD src_port
+#define LAST_TUNNEL_FIELD tunnel_id
/* Field is the last supported field */
#define FIELDS_NOT_SUPPORTED(filter, field)\
@@ -1527,155 +1582,164 @@ static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
static int parse_flow_attr(u32 *match_c, u32 *match_v,
const union ib_flow_spec *ib_spec)
{
- void *outer_headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
- outer_headers);
- void *outer_headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
- outer_headers);
void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
misc_parameters);
void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v,
misc_parameters);
+ void *headers_c;
+ void *headers_v;
+
+ if (ib_spec->type & IB_FLOW_SPEC_INNER) {
+ headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
+ inner_headers);
+ headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
+ inner_headers);
+ } else {
+ headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
+ outer_headers);
+ headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
+ outer_headers);
+ }
- switch (ib_spec->type) {
+ switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {
case IB_FLOW_SPEC_ETH:
if (FIELDS_NOT_SUPPORTED(ib_spec->eth.mask, LAST_ETH_FIELD))
return -ENOTSUPP;
- ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
dmac_47_16),
ib_spec->eth.mask.dst_mac);
- ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v,
+ ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
dmac_47_16),
ib_spec->eth.val.dst_mac);
- ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
smac_47_16),
ib_spec->eth.mask.src_mac);
- ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v,
+ ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
smac_47_16),
ib_spec->eth.val.src_mac);
if (ib_spec->eth.mask.vlan_tag) {
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
vlan_tag, 1);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
vlan_tag, 1);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
first_vid, ntohs(ib_spec->eth.mask.vlan_tag));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
first_vid, ntohs(ib_spec->eth.val.vlan_tag));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
first_cfi,
ntohs(ib_spec->eth.mask.vlan_tag) >> 12);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
first_cfi,
ntohs(ib_spec->eth.val.vlan_tag) >> 12);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
first_prio,
ntohs(ib_spec->eth.mask.vlan_tag) >> 13);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
first_prio,
ntohs(ib_spec->eth.val.vlan_tag) >> 13);
}
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
ethertype, ntohs(ib_spec->eth.mask.ether_type));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
ethertype, ntohs(ib_spec->eth.val.ether_type));
break;
case IB_FLOW_SPEC_IPV4:
if (FIELDS_NOT_SUPPORTED(ib_spec->ipv4.mask, LAST_IPV4_FIELD))
return -ENOTSUPP;
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
ethertype, 0xffff);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
ethertype, ETH_P_IP);
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
src_ipv4_src_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.mask.src_ip,
sizeof(ib_spec->ipv4.mask.src_ip));
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
src_ipv4_src_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.val.src_ip,
sizeof(ib_spec->ipv4.val.src_ip));
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.mask.dst_ip,
sizeof(ib_spec->ipv4.mask.dst_ip));
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.val.dst_ip,
sizeof(ib_spec->ipv4.val.dst_ip));
- set_tos(outer_headers_c, outer_headers_v,
+ set_tos(headers_c, headers_v,
ib_spec->ipv4.mask.tos, ib_spec->ipv4.val.tos);
- set_proto(outer_headers_c, outer_headers_v,
+ set_proto(headers_c, headers_v,
ib_spec->ipv4.mask.proto, ib_spec->ipv4.val.proto);
break;
case IB_FLOW_SPEC_IPV6:
if (FIELDS_NOT_SUPPORTED(ib_spec->ipv6.mask, LAST_IPV6_FIELD))
return -ENOTSUPP;
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c,
ethertype, 0xffff);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v,
ethertype, ETH_P_IPV6);
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
src_ipv4_src_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.mask.src_ip,
sizeof(ib_spec->ipv6.mask.src_ip));
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
src_ipv4_src_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.val.src_ip,
sizeof(ib_spec->ipv6.val.src_ip));
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.mask.dst_ip,
sizeof(ib_spec->ipv6.mask.dst_ip));
- memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v,
+ memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.val.dst_ip,
sizeof(ib_spec->ipv6.val.dst_ip));
- set_tos(outer_headers_c, outer_headers_v,
+ set_tos(headers_c, headers_v,
ib_spec->ipv6.mask.traffic_class,
ib_spec->ipv6.val.traffic_class);
- set_proto(outer_headers_c, outer_headers_v,
+ set_proto(headers_c, headers_v,
ib_spec->ipv6.mask.next_hdr,
ib_spec->ipv6.val.next_hdr);
- MLX5_SET(fte_match_set_misc, misc_params_c,
- outer_ipv6_flow_label,
- ntohl(ib_spec->ipv6.mask.flow_label));
- MLX5_SET(fte_match_set_misc, misc_params_v,
- outer_ipv6_flow_label,
- ntohl(ib_spec->ipv6.val.flow_label));
+ set_flow_label(misc_params_c, misc_params_v,
+ ntohl(ib_spec->ipv6.mask.flow_label),
+ ntohl(ib_spec->ipv6.val.flow_label),
+ ib_spec->type & IB_FLOW_SPEC_INNER);
+
break;
case IB_FLOW_SPEC_TCP:
if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask,
LAST_TCP_UDP_FIELD))
return -ENOTSUPP;
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
0xff);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, ip_protocol,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
IPPROTO_TCP);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_sport,
ntohs(ib_spec->tcp_udp.mask.src_port));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, tcp_sport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_sport,
ntohs(ib_spec->tcp_udp.val.src_port));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_dport,
ntohs(ib_spec->tcp_udp.mask.dst_port));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, tcp_dport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_dport,
ntohs(ib_spec->tcp_udp.val.dst_port));
break;
case IB_FLOW_SPEC_UDP:
@@ -1683,21 +1747,31 @@ static int parse_flow_attr(u32 *match_c, u32 *match_v,
LAST_TCP_UDP_FIELD))
return -ENOTSUPP;
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
0xff);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, ip_protocol,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
IPPROTO_UDP);
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, udp_sport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_sport,
ntohs(ib_spec->tcp_udp.mask.src_port));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, udp_sport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_sport,
ntohs(ib_spec->tcp_udp.val.src_port));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, udp_dport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_dport,
ntohs(ib_spec->tcp_udp.mask.dst_port));
- MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, udp_dport,
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
ntohs(ib_spec->tcp_udp.val.dst_port));
break;
+ case IB_FLOW_SPEC_VXLAN_TUNNEL:
+ if (FIELDS_NOT_SUPPORTED(ib_spec->tunnel.mask,
+ LAST_TUNNEL_FIELD))
+ return -ENOTSUPP;
+
+ MLX5_SET(fte_match_set_misc, misc_params_c, vxlan_vni,
+ ntohl(ib_spec->tunnel.mask.tunnel_id));
+ MLX5_SET(fte_match_set_misc, misc_params_v, vxlan_vni,
+ ntohl(ib_spec->tunnel.val.tunnel_id));
+ break;
default:
return -EINVAL;
}
@@ -2721,6 +2795,8 @@ static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
struct ib_port_immutable *immutable)
{
struct ib_port_attr attr;
+ struct mlx5_ib_dev *dev = to_mdev(ibdev);
+ enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, port_num);
int err;
err = mlx5_ib_query_port(ibdev, port_num, &attr);
@@ -2730,7 +2806,8 @@ 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 = get_core_cap_flags(ibdev);
- immutable->max_mad_size = IB_MGMT_MAD_SIZE;
+ if ((ll == IB_LINK_LAYER_INFINIBAND) || MLX5_CAP_GEN(dev->mdev, roce))
+ immutable->max_mad_size = IB_MGMT_MAD_SIZE;
return 0;
}
@@ -2744,7 +2821,7 @@ static void get_dev_fw_str(struct ib_device *ibdev, char *str,
fw_rev_min(dev->mdev), fw_rev_sub(dev->mdev));
}
-static int mlx5_roce_lag_init(struct mlx5_ib_dev *dev)
+static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
{
struct mlx5_core_dev *mdev = dev->mdev;
struct mlx5_flow_namespace *ns = mlx5_get_flow_namespace(mdev,
@@ -2773,7 +2850,7 @@ err_destroy_vport_lag:
return err;
}
-static void mlx5_roce_lag_cleanup(struct mlx5_ib_dev *dev)
+static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)
{
struct mlx5_core_dev *mdev = dev->mdev;
@@ -2785,7 +2862,21 @@ static void mlx5_roce_lag_cleanup(struct mlx5_ib_dev *dev)
}
}
-static void mlx5_remove_roce_notifier(struct mlx5_ib_dev *dev)
+static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev)
+{
+ int err;
+
+ dev->roce.nb.notifier_call = mlx5_netdev_event;
+ err = register_netdevice_notifier(&dev->roce.nb);
+ if (err) {
+ dev->roce.nb.notifier_call = NULL;
+ return err;
+ }
+
+ return 0;
+}
+
+static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev)
{
if (dev->roce.nb.notifier_call) {
unregister_netdevice_notifier(&dev->roce.nb);
@@ -2793,39 +2884,40 @@ static void mlx5_remove_roce_notifier(struct mlx5_ib_dev *dev)
}
}
-static int mlx5_enable_roce(struct mlx5_ib_dev *dev)
+static int mlx5_enable_eth(struct mlx5_ib_dev *dev)
{
int err;
- dev->roce.nb.notifier_call = mlx5_netdev_event;
- err = register_netdevice_notifier(&dev->roce.nb);
- if (err) {
- dev->roce.nb.notifier_call = NULL;
+ err = mlx5_add_netdev_notifier(dev);
+ if (err)
return err;
- }
- err = mlx5_nic_vport_enable_roce(dev->mdev);
- if (err)
- goto err_unregister_netdevice_notifier;
+ if (MLX5_CAP_GEN(dev->mdev, roce)) {
+ err = mlx5_nic_vport_enable_roce(dev->mdev);
+ if (err)
+ goto err_unregister_netdevice_notifier;
+ }
- err = mlx5_roce_lag_init(dev);
+ err = mlx5_eth_lag_init(dev);
if (err)
goto err_disable_roce;
return 0;
err_disable_roce:
- mlx5_nic_vport_disable_roce(dev->mdev);
+ if (MLX5_CAP_GEN(dev->mdev, roce))
+ mlx5_nic_vport_disable_roce(dev->mdev);
err_unregister_netdevice_notifier:
- mlx5_remove_roce_notifier(dev);
+ mlx5_remove_netdev_notifier(dev);
return err;
}
-static void mlx5_disable_roce(struct mlx5_ib_dev *dev)
+static void mlx5_disable_eth(struct mlx5_ib_dev *dev)
{
- mlx5_roce_lag_cleanup(dev);
- mlx5_nic_vport_disable_roce(dev->mdev);
+ mlx5_eth_lag_cleanup(dev);
+ if (MLX5_CAP_GEN(dev->mdev, roce))
+ mlx5_nic_vport_disable_roce(dev->mdev);
}
static void mlx5_ib_dealloc_q_counters(struct mlx5_ib_dev *dev)
@@ -2947,9 +3039,6 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
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);
dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
@@ -2995,6 +3084,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
(1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
(1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
(1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_AH) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_AH) |
(1ull << IB_USER_VERBS_CMD_REG_MR) |
(1ull << IB_USER_VERBS_CMD_REREG_MR) |
(1ull << IB_USER_VERBS_CMD_DEREG_MR) |
@@ -3017,7 +3108,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
dev->ib_dev.uverbs_ex_cmd_mask =
(1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE) |
(1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ) |
- (1ull << IB_USER_VERBS_EX_CMD_CREATE_QP);
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_QP) |
+ (1ull << IB_USER_VERBS_EX_CMD_MODIFY_QP);
dev->ib_dev.query_device = mlx5_ib_query_device;
dev->ib_dev.query_port = mlx5_ib_query_port;
@@ -3128,14 +3220,14 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
spin_lock_init(&dev->reset_flow_resource_lock);
if (ll == IB_LINK_LAYER_ETHERNET) {
- err = mlx5_enable_roce(dev);
+ err = mlx5_enable_eth(dev);
if (err)
goto err_free_port;
}
err = create_dev_resources(&dev->devr);
if (err)
- goto err_disable_roce;
+ goto err_disable_eth;
err = mlx5_ib_odp_init_one(dev);
if (err)
@@ -3179,10 +3271,10 @@ err_odp:
err_rsrc:
destroy_dev_resources(&dev->devr);
-err_disable_roce:
+err_disable_eth:
if (ll == IB_LINK_LAYER_ETHERNET) {
- mlx5_disable_roce(dev);
- mlx5_remove_roce_notifier(dev);
+ mlx5_disable_eth(dev);
+ mlx5_remove_netdev_notifier(dev);
}
err_free_port:
@@ -3199,14 +3291,14 @@ 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);
- mlx5_remove_roce_notifier(dev);
+ mlx5_remove_netdev_notifier(dev);
ib_unregister_device(&dev->ib_dev);
mlx5_ib_dealloc_q_counters(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);
+ mlx5_disable_eth(dev);
kfree(dev->port);
ib_dealloc_device(&dev->ib_dev);
}
diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c
index 996b54e366b0..6851357c16f4 100644
--- a/drivers/infiniband/hw/mlx5/mem.c
+++ b/drivers/infiniband/hw/mlx5/mem.c
@@ -37,12 +37,15 @@
/* @umem: umem object to scan
* @addr: ib virtual address requested by the user
+ * @max_page_shift: high limit for page_shift - 0 means no limit
* @count: number of PAGE_SIZE pages covered by umem
* @shift: page shift for the compound pages found in the region
* @ncont: number of compund pages
* @order: log2 of the number of compound pages
*/
-void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
+void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr,
+ unsigned long max_page_shift,
+ int *count, int *shift,
int *ncont, int *order)
{
unsigned long tmp;
@@ -72,6 +75,8 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
addr = addr >> page_shift;
tmp = (unsigned long)addr;
m = find_first_bit(&tmp, BITS_PER_LONG);
+ if (max_page_shift)
+ m = min_t(unsigned long, max_page_shift - page_shift, m);
skip = 1 << m;
mask = skip - 1;
i = 0;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 854748b61212..6c6057eb60ea 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -63,6 +63,8 @@ pr_warn("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__, \
#define MLX5_IB_DEFAULT_UIDX 0xffffff
#define MLX5_USER_ASSIGNED_UIDX_MASK __mlx5_mask(qpc, user_index)
+#define MLX5_MKEY_PAGE_SHIFT_MASK __mlx5_mask(mkc, log_page_size)
+
enum {
MLX5_IB_MMAP_CMD_SHIFT = 8,
MLX5_IB_MMAP_CMD_MASK = 0xff,
@@ -387,6 +389,7 @@ struct mlx5_ib_qp {
struct list_head qps_list;
struct list_head cq_recv_list;
struct list_head cq_send_list;
+ u32 rate_limit;
};
struct mlx5_ib_cq_buf {
@@ -418,7 +421,7 @@ struct mlx5_umr_wr {
struct ib_pd *pd;
unsigned int page_shift;
unsigned int npages;
- u32 length;
+ u64 length;
int access_flags;
u32 mkey;
};
@@ -739,7 +742,8 @@ 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 *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
+struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata);
int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
int mlx5_ib_destroy_ah(struct ib_ah *ah);
struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
@@ -825,7 +829,9 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props);
int mlx5_ib_init_fmr(struct mlx5_ib_dev *dev);
void mlx5_ib_cleanup_fmr(struct mlx5_ib_dev *dev);
-void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
+void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr,
+ unsigned long max_page_shift,
+ int *count, int *shift,
int *ncont, int *order);
void __mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem,
int page_shift, size_t offset, size_t num_pages,
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 4e9012463c37..8f608debe141 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -628,7 +628,8 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
ent->order = i + 2;
ent->dev = dev;
- if (dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE)
+ if ((dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE) &&
+ (mlx5_core_is_pf(dev->mdev)))
limit = dev->mdev->profile->mr_cache[i].limit;
else
limit = 0;
@@ -646,6 +647,33 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
return 0;
}
+static void wait_for_async_commands(struct mlx5_ib_dev *dev)
+{
+ struct mlx5_mr_cache *cache = &dev->cache;
+ struct mlx5_cache_ent *ent;
+ int total = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
+ ent = &cache->ent[i];
+ for (j = 0 ; j < 1000; j++) {
+ if (!ent->pending)
+ break;
+ msleep(50);
+ }
+ }
+ for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
+ ent = &cache->ent[i];
+ total += ent->pending;
+ }
+
+ if (total)
+ mlx5_ib_warn(dev, "aborted while there are %d pending mr requests\n", total);
+ else
+ mlx5_ib_warn(dev, "done with all pending requests\n");
+}
+
int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
{
int i;
@@ -659,6 +687,7 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
clean_keys(dev, i);
destroy_workqueue(dev->cache.wq);
+ wait_for_async_commands(dev);
del_timer_sync(&dev->delay_timer);
return 0;
@@ -816,29 +845,34 @@ static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev,
umrwr->mkey = key;
}
-static struct ib_umem *mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
- int access_flags, int *npages,
- int *page_shift, int *ncont, int *order)
+static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
+ int access_flags, struct ib_umem **umem,
+ int *npages, int *page_shift, int *ncont,
+ int *order)
{
struct mlx5_ib_dev *dev = to_mdev(pd->device);
- struct ib_umem *umem = ib_umem_get(pd->uobject->context, start, length,
- access_flags, 0);
- if (IS_ERR(umem)) {
+ int err;
+
+ *umem = ib_umem_get(pd->uobject->context, start, length,
+ access_flags, 0);
+ err = PTR_ERR_OR_ZERO(*umem);
+ if (err < 0) {
mlx5_ib_err(dev, "umem get failed (%ld)\n", PTR_ERR(umem));
- return (void *)umem;
+ return err;
}
- mlx5_ib_cont_pages(umem, start, npages, page_shift, ncont, order);
+ mlx5_ib_cont_pages(*umem, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages,
+ page_shift, ncont, order);
if (!*npages) {
mlx5_ib_warn(dev, "avoid zero region\n");
- ib_umem_release(umem);
- return ERR_PTR(-EINVAL);
+ ib_umem_release(*umem);
+ return -EINVAL;
}
mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n",
*npages, *ncont, *order, *page_shift);
- return umem;
+ return 0;
}
static void mlx5_ib_umr_done(struct ib_cq *cq, struct ib_wc *wc)
@@ -1164,11 +1198,11 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n",
start, virt_addr, length, access_flags);
- umem = mr_umem_get(pd, start, length, access_flags, &npages,
+ err = mr_umem_get(pd, start, length, access_flags, &umem, &npages,
&page_shift, &ncont, &order);
- if (IS_ERR(umem))
- return (void *)umem;
+ if (err < 0)
+ return ERR_PTR(err);
if (use_umr(order)) {
mr = reg_umr(pd, umem, virt_addr, length, ncont, page_shift,
@@ -1345,10 +1379,9 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
*/
flags |= IB_MR_REREG_TRANS;
ib_umem_release(mr->umem);
- mr->umem = mr_umem_get(pd, addr, len, access_flags, &npages,
- &page_shift, &ncont, &order);
- if (IS_ERR(mr->umem)) {
- err = PTR_ERR(mr->umem);
+ err = mr_umem_get(pd, addr, len, access_flags, &mr->umem,
+ &npages, &page_shift, &ncont, &order);
+ if (err < 0) {
mr->umem = NULL;
return err;
}
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index d1e921816bfe..a1b3125f0a6e 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -77,12 +77,14 @@ struct mlx5_wqe_eth_pad {
enum raw_qp_set_mask_map {
MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID = 1UL << 0,
+ MLX5_RAW_QP_RATE_LIMIT = 1UL << 1,
};
struct mlx5_modify_raw_qp_param {
u16 operation;
u32 set_mask; /* raw_qp_set_mask_map */
+ u32 rate_limit;
u8 rq_q_ctr_id;
};
@@ -351,6 +353,29 @@ static int calc_send_wqe(struct ib_qp_init_attr *attr)
return ALIGN(max_t(int, inl_size, size), MLX5_SEND_WQE_BB);
}
+static int get_send_sge(struct ib_qp_init_attr *attr, int wqe_size)
+{
+ int max_sge;
+
+ if (attr->qp_type == IB_QPT_RC)
+ max_sge = (min_t(int, wqe_size, 512) -
+ sizeof(struct mlx5_wqe_ctrl_seg) -
+ sizeof(struct mlx5_wqe_raddr_seg)) /
+ sizeof(struct mlx5_wqe_data_seg);
+ else if (attr->qp_type == IB_QPT_XRC_INI)
+ max_sge = (min_t(int, wqe_size, 512) -
+ sizeof(struct mlx5_wqe_ctrl_seg) -
+ sizeof(struct mlx5_wqe_xrc_seg) -
+ sizeof(struct mlx5_wqe_raddr_seg)) /
+ sizeof(struct mlx5_wqe_data_seg);
+ else
+ max_sge = (wqe_size - sq_overhead(attr)) /
+ sizeof(struct mlx5_wqe_data_seg);
+
+ return min_t(int, max_sge, wqe_size - sq_overhead(attr) /
+ sizeof(struct mlx5_wqe_data_seg));
+}
+
static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
struct mlx5_ib_qp *qp)
{
@@ -381,13 +406,18 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
wq_size = roundup_pow_of_two(attr->cap.max_send_wr * wqe_size);
qp->sq.wqe_cnt = wq_size / MLX5_SEND_WQE_BB;
if (qp->sq.wqe_cnt > (1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz))) {
- mlx5_ib_dbg(dev, "wqe count(%d) exceeds limits(%d)\n",
+ mlx5_ib_dbg(dev, "send queue size (%d * %d / %d -> %d) exceeds limits(%d)\n",
+ attr->cap.max_send_wr, wqe_size, MLX5_SEND_WQE_BB,
qp->sq.wqe_cnt,
1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz));
return -ENOMEM;
}
qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
- qp->sq.max_gs = attr->cap.max_send_sge;
+ qp->sq.max_gs = get_send_sge(attr, wqe_size);
+ if (qp->sq.max_gs < attr->cap.max_send_sge)
+ return -ENOMEM;
+
+ attr->cap.max_send_sge = qp->sq.max_gs;
qp->sq.max_post = wq_size / wqe_size;
attr->cap.max_send_wr = qp->sq.max_post;
@@ -647,7 +677,7 @@ static int mlx5_ib_umem_get(struct mlx5_ib_dev *dev,
return PTR_ERR(*umem);
}
- mlx5_ib_cont_pages(*umem, addr, npages, page_shift, ncont, NULL);
+ mlx5_ib_cont_pages(*umem, addr, 0, npages, page_shift, ncont, NULL);
err = mlx5_ib_get_buf_offset(addr, *page_shift, offset);
if (err) {
@@ -700,7 +730,7 @@ static int create_user_rq(struct mlx5_ib_dev *dev, struct ib_pd *pd,
return err;
}
- mlx5_ib_cont_pages(rwq->umem, ucmd->buf_addr, &npages, &page_shift,
+ mlx5_ib_cont_pages(rwq->umem, ucmd->buf_addr, 0, &npages, &page_shift,
&ncont, NULL);
err = mlx5_ib_get_buf_offset(ucmd->buf_addr, page_shift,
&rwq->rq_page_offset);
@@ -2442,8 +2472,14 @@ out:
}
static int modify_raw_packet_qp_sq(struct mlx5_core_dev *dev,
- struct mlx5_ib_sq *sq, int new_state)
+ struct mlx5_ib_sq *sq,
+ int new_state,
+ const struct mlx5_modify_raw_qp_param *raw_qp_param)
{
+ struct mlx5_ib_qp *ibqp = sq->base.container_mibqp;
+ u32 old_rate = ibqp->rate_limit;
+ u32 new_rate = old_rate;
+ u16 rl_index = 0;
void *in;
void *sqc;
int inlen;
@@ -2459,10 +2495,44 @@ static int modify_raw_packet_qp_sq(struct mlx5_core_dev *dev,
sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
MLX5_SET(sqc, sqc, state, new_state);
+ if (raw_qp_param->set_mask & MLX5_RAW_QP_RATE_LIMIT) {
+ if (new_state != MLX5_SQC_STATE_RDY)
+ pr_warn("%s: Rate limit can only be changed when SQ is moving to RDY\n",
+ __func__);
+ else
+ new_rate = raw_qp_param->rate_limit;
+ }
+
+ if (old_rate != new_rate) {
+ if (new_rate) {
+ err = mlx5_rl_add_rate(dev, new_rate, &rl_index);
+ if (err) {
+ pr_err("Failed configuring rate %u: %d\n",
+ new_rate, err);
+ goto out;
+ }
+ }
+
+ MLX5_SET64(modify_sq_in, in, modify_bitmask, 1);
+ MLX5_SET(sqc, sqc, packet_pacing_rate_limit_index, rl_index);
+ }
+
err = mlx5_core_modify_sq(dev, sq->base.mqp.qpn, in, inlen);
- if (err)
+ if (err) {
+ /* Remove new rate from table if failed */
+ if (new_rate &&
+ old_rate != new_rate)
+ mlx5_rl_remove_rate(dev, new_rate);
goto out;
+ }
+
+ /* Only remove the old rate after new rate was set */
+ if ((old_rate &&
+ (old_rate != new_rate)) ||
+ (new_state != MLX5_SQC_STATE_RDY))
+ mlx5_rl_remove_rate(dev, old_rate);
+ ibqp->rate_limit = new_rate;
sq->state = new_state;
out:
@@ -2477,6 +2547,8 @@ static int modify_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_rq *rq = &raw_packet_qp->rq;
struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
+ int modify_rq = !!qp->rq.wqe_cnt;
+ int modify_sq = !!qp->sq.wqe_cnt;
int rq_state;
int sq_state;
int err;
@@ -2494,10 +2566,18 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *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:
+ if (raw_qp_param->set_mask ==
+ MLX5_RAW_QP_RATE_LIMIT) {
+ modify_rq = 0;
+ sq_state = sq->state;
+ } else {
+ return raw_qp_param->set_mask ? -EINVAL : 0;
+ }
+ break;
+ case MLX5_CMD_OP_INIT2INIT_QP:
+ case MLX5_CMD_OP_INIT2RTR_QP:
if (raw_qp_param->set_mask)
return -EINVAL;
else
@@ -2507,13 +2587,13 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
return -EINVAL;
}
- if (qp->rq.wqe_cnt) {
- err = modify_raw_packet_qp_rq(dev, rq, rq_state, raw_qp_param);
+ if (modify_rq) {
+ err = modify_raw_packet_qp_rq(dev, rq, rq_state, raw_qp_param);
if (err)
return err;
}
- if (qp->sq.wqe_cnt) {
+ if (modify_sq) {
if (tx_affinity) {
err = modify_raw_packet_tx_affinity(dev->mdev, sq,
tx_affinity);
@@ -2521,7 +2601,7 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
return err;
}
- return modify_raw_packet_qp_sq(dev->mdev, sq, sq_state);
+ return modify_raw_packet_qp_sq(dev->mdev, sq, sq_state, raw_qp_param);
}
return 0;
@@ -2577,7 +2657,6 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
struct mlx5_ib_port *mibport = NULL;
enum mlx5_qp_state mlx5_cur, mlx5_new;
enum mlx5_qp_optpar optpar;
- int sqd_event;
int mlx5_st;
int err;
u16 op;
@@ -2724,12 +2803,6 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
if (qp->rq.wqe_cnt && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
context->db_rec_addr = cpu_to_be64(qp->db.dma);
- if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD &&
- attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY && attr->en_sqd_async_notify)
- sqd_event = 1;
- else
- sqd_event = 0;
-
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
u8 port_num = (attr_mask & IB_QP_PORT ? attr->port_num :
qp->port) - 1;
@@ -2776,6 +2849,12 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
raw_qp_param.rq_q_ctr_id = mibport->q_cnt_id;
raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;
}
+
+ if (attr_mask & IB_QP_RATE_LIMIT) {
+ raw_qp_param.rate_limit = attr->rate_limit;
+ raw_qp_param.set_mask |= MLX5_RAW_QP_RATE_LIMIT;
+ }
+
err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
} else {
err = mlx5_core_qp_modify(dev->mdev, op, optpar, context,
@@ -3067,10 +3146,10 @@ static void set_linv_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr)
{
memset(umr, 0, sizeof(*umr));
umr->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE);
- umr->flags = 1 << 7;
+ umr->flags = MLX5_UMR_INLINE;
}
-static __be64 get_umr_reg_mr_mask(void)
+static __be64 get_umr_reg_mr_mask(int atomic)
{
u64 result;
@@ -3083,9 +3162,11 @@ static __be64 get_umr_reg_mr_mask(void)
MLX5_MKEY_MASK_KEY |
MLX5_MKEY_MASK_RR |
MLX5_MKEY_MASK_RW |
- MLX5_MKEY_MASK_A |
MLX5_MKEY_MASK_FREE;
+ if (atomic)
+ result |= MLX5_MKEY_MASK_A;
+
return cpu_to_be64(result);
}
@@ -3146,7 +3227,7 @@ static __be64 get_umr_update_pd_mask(void)
}
static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
- struct ib_send_wr *wr)
+ struct ib_send_wr *wr, int atomic)
{
struct mlx5_umr_wr *umrwr = umr_wr(wr);
@@ -3171,7 +3252,7 @@ static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_PD)
umr->mkey_mask |= get_umr_update_pd_mask();
if (!umr->mkey_mask)
- umr->mkey_mask = get_umr_reg_mr_mask();
+ umr->mkey_mask = get_umr_reg_mr_mask(atomic);
} else {
umr->mkey_mask = get_umr_unreg_mr_mask();
}
@@ -4024,7 +4105,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
}
qp->sq.wr_data[idx] = MLX5_IB_WR_UMR;
ctrl->imm = cpu_to_be32(umr_wr(wr)->mkey);
- set_reg_umr_segment(seg, wr);
+ set_reg_umr_segment(seg, wr, !!(MLX5_CAP_GEN(mdev, atomic)));
seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
if (unlikely((seg == qend)))
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 3857dbd9c956..6f4397ee1ed6 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -118,7 +118,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
return err;
}
- mlx5_ib_cont_pages(srq->umem, ucmd.buf_addr, &npages,
+ mlx5_ib_cont_pages(srq->umem, ucmd.buf_addr, 0, &npages,
&page_shift, &ncont, NULL);
err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift,
&offset);
@@ -203,8 +203,6 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
srq->wrid = kmalloc(srq->msrq.max * sizeof(u64), GFP_KERNEL);
if (!srq->wrid) {
- mlx5_ib_dbg(dev, "kmalloc failed %lu\n",
- (unsigned long)(srq->msrq.max * sizeof(u64)));
err = -ENOMEM;
goto err_in;
}
@@ -282,6 +280,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n",
desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs,
srq->msrq.max_avail_gather);
+ in.type = init_attr->srq_type;
if (pd->uobject)
err = create_srq_user(pd, srq, &in, udata, buf_size);
@@ -294,7 +293,6 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
goto err_srq;
}
- in.type = init_attr->srq_type;
in.log_size = ilog2(srq->msrq.max);
in.wqe_shift = srq->msrq.wqe_shift - 4;
if (srq->wq_sig)
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index bcac294042f5..c9f0f364f484 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -186,8 +186,8 @@ int mthca_create_ah(struct mthca_dev *dev,
on_hca_fail:
if (ah->type == MTHCA_AH_PCI_POOL) {
- ah->av = pci_pool_alloc(dev->av_table.pool,
- GFP_ATOMIC, &ah->avdma);
+ ah->av = pci_pool_zalloc(dev->av_table.pool,
+ GFP_ATOMIC, &ah->avdma);
if (!ah->av)
return -ENOMEM;
@@ -196,8 +196,6 @@ on_hca_fail:
ah->key = pd->ntmr.ibmr.lkey;
- memset(av, 0, MTHCA_AV_SIZE);
-
av->port_pd = cpu_to_be32(pd->pd_num | (ah_attr->port_num << 24));
av->g_slid = ah_attr->src_path_bits;
av->dlid = cpu_to_be16(ah_attr->dlid);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 358930a41e36..d31708742ba5 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -410,7 +410,9 @@ static int mthca_dealloc_pd(struct ib_pd *pd)
}
static struct ib_ah *mthca_ah_create(struct ib_pd *pd,
- struct ib_ah_attr *ah_attr)
+ struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
+
{
int err;
struct mthca_ah *ah;
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 6727af27c017..2a6979e4ae1c 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -96,8 +96,6 @@ int mthca_reset(struct mthca_dev *mdev)
hca_header = kmalloc(256, GFP_KERNEL);
if (!hca_header) {
err = -ENOMEM;
- mthca_err(mdev, "Couldn't allocate memory to save HCA "
- "PCI header, aborting.\n");
goto put_dev;
}
@@ -119,8 +117,6 @@ int mthca_reset(struct mthca_dev *mdev)
bridge_header = kmalloc(256, GFP_KERNEL);
if (!bridge_header) {
err = -ENOMEM;
- mthca_err(mdev, "Couldn't allocate memory to save HCA "
- "bridge PCI header, aborting.\n");
goto free_hca;
}
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 2baa45a8e401..5b9601014f0c 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -515,7 +515,6 @@ static int nes_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
/* Allocate hardware structure */
nesdev = kzalloc(sizeof(struct nes_device), GFP_KERNEL);
if (!nesdev) {
- printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n", pci_name(pcidev));
ret = -ENOMEM;
goto bail2;
}
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 57db9b332f44..8e703479e7ce 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -2282,10 +2282,8 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
if (!listener) {
/* create a CM listen node (1/2 node to compare incoming traffic to) */
listener = kzalloc(sizeof(*listener), GFP_ATOMIC);
- if (!listener) {
- nes_debug(NES_DBG_CM, "Not creating listener memory allocation failed\n");
+ if (!listener)
return NULL;
- }
listener->loc_addr = cm_info->loc_addr;
listener->loc_port = cm_info->loc_port;
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index a1c6481d8038..19acd13c6cb1 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -351,9 +351,8 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
/* allocate a new adapter struct */
nesadapter = kzalloc(adapter_size, GFP_KERNEL);
- if (nesadapter == NULL) {
+ if (!nesadapter)
return NULL;
- }
nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n",
nesadapter, (u32)sizeof(struct nes_adapter), adapter_size);
@@ -1007,8 +1006,7 @@ int nes_init_cqp(struct nes_device *nesdev)
/* Allocate a twice the number of CQP requests as the SQ size */
nesdev->nes_cqp_requests = kzalloc(sizeof(struct nes_cqp_request) *
2 * NES_CQP_SQ_SIZE, GFP_KERNEL);
- if (nesdev->nes_cqp_requests == NULL) {
- nes_debug(NES_DBG_INIT, "Unable to allocate memory CQP request entries.\n");
+ if (!nesdev->nes_cqp_requests) {
pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase,
nesdev->cqp.sq_pbase);
return -ENOMEM;
diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c
index 416645259b0f..33624f17c347 100644
--- a/drivers/infiniband/hw/nes/nes_mgt.c
+++ b/drivers/infiniband/hw/nes/nes_mgt.c
@@ -320,8 +320,7 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
/* Found one */
fpdu_info = kzalloc(sizeof(*fpdu_info), GFP_ATOMIC);
- if (fpdu_info == NULL) {
- nes_debug(NES_DBG_PAU, "Failed to alloc a fpdu_info.\n");
+ if (!fpdu_info) {
rc = -ENOMEM;
goto out;
}
@@ -729,8 +728,7 @@ static int nes_change_quad_hash(struct nes_device *nesdev,
}
qh_chg = kmalloc(sizeof *qh_chg, GFP_ATOMIC);
- if (qh_chg == NULL) {
- nes_debug(NES_DBG_PAU, "Failed to get a cqp_request.\n");
+ if (!qh_chg) {
ret = -ENOMEM;
goto chg_qh_err;
}
@@ -880,10 +878,8 @@ int nes_init_mgt_qp(struct nes_device *nesdev, struct net_device *netdev, struct
/* Allocate space the all mgt QPs once */
mgtvnic = kzalloc(NES_MGT_QP_COUNT * sizeof(struct nes_vnic_mgt), GFP_KERNEL);
- if (mgtvnic == NULL) {
- nes_debug(NES_DBG_INIT, "Unable to allocate memory for mgt structure\n");
+ if (!mgtvnic)
return -ENOMEM;
- }
/* Allocate fragment, RQ, and CQ; Reuse CEQ based on the PCI function */
/* We are not sending from this NIC so sq is not allocated */
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 7f8597d6738b..5921ea3d50ae 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -662,10 +662,14 @@ tso_sq_no_longer_full:
nesnic->sq_head &= nesnic->sq_size-1;
}
} else {
- nesvnic->linearized_skbs++;
hoffset = skb_transport_header(skb) - skb->data;
nhoffset = skb_network_header(skb) - skb->data;
- skb_linearize(skb);
+ if (skb_linearize(skb)) {
+ nesvnic->tx_sw_dropped++;
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ nesvnic->linearized_skbs++;
skb_set_transport_header(skb, hoffset);
skb_set_network_header(skb, nhoffset);
if (!nes_nic_send(skb, netdev))
@@ -1461,7 +1465,8 @@ static int nes_netdev_set_pauseparam(struct net_device *netdev,
/**
* nes_netdev_get_settings
*/
-static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd *et_cmd)
+static int nes_netdev_get_link_ksettings(struct net_device *netdev,
+ struct ethtool_link_ksettings *cmd)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
@@ -1470,54 +1475,59 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
u8 phy_type = nesadapter->phy_type[mac_index];
u8 phy_index = nesadapter->phy_index[mac_index];
u16 phy_data;
+ u32 supported, advertising;
- et_cmd->duplex = DUPLEX_FULL;
- et_cmd->port = PORT_MII;
- et_cmd->maxtxpkt = 511;
- et_cmd->maxrxpkt = 511;
+ cmd->base.duplex = DUPLEX_FULL;
+ cmd->base.port = PORT_MII;
if (nesadapter->OneG_Mode) {
- ethtool_cmd_speed_set(et_cmd, SPEED_1000);
+ cmd->base.speed = SPEED_1000;
if (phy_type == NES_PHY_TYPE_PUMA_1G) {
- et_cmd->supported = SUPPORTED_1000baseT_Full;
- et_cmd->advertising = ADVERTISED_1000baseT_Full;
- et_cmd->autoneg = AUTONEG_DISABLE;
- et_cmd->transceiver = XCVR_INTERNAL;
- et_cmd->phy_address = mac_index;
+ supported = SUPPORTED_1000baseT_Full;
+ advertising = ADVERTISED_1000baseT_Full;
+ cmd->base.autoneg = AUTONEG_DISABLE;
+ cmd->base.phy_address = mac_index;
} else {
unsigned long flags;
- et_cmd->supported = SUPPORTED_1000baseT_Full
- | SUPPORTED_Autoneg;
- et_cmd->advertising = ADVERTISED_1000baseT_Full
- | ADVERTISED_Autoneg;
+
+ supported = SUPPORTED_1000baseT_Full
+ | SUPPORTED_Autoneg;
+ advertising = ADVERTISED_1000baseT_Full
+ | ADVERTISED_Autoneg;
spin_lock_irqsave(&nesadapter->phy_lock, flags);
nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
if (phy_data & 0x1000)
- et_cmd->autoneg = AUTONEG_ENABLE;
+ cmd->base.autoneg = AUTONEG_ENABLE;
else
- et_cmd->autoneg = AUTONEG_DISABLE;
- et_cmd->transceiver = XCVR_EXTERNAL;
- et_cmd->phy_address = phy_index;
+ cmd->base.autoneg = AUTONEG_DISABLE;
+ cmd->base.phy_address = phy_index;
}
+ ethtool_convert_legacy_u32_to_link_mode(
+ cmd->link_modes.supported, supported);
+ ethtool_convert_legacy_u32_to_link_mode(
+ cmd->link_modes.advertising, advertising);
return 0;
}
if ((phy_type == NES_PHY_TYPE_ARGUS) ||
(phy_type == NES_PHY_TYPE_SFP_D) ||
(phy_type == NES_PHY_TYPE_KR)) {
- et_cmd->transceiver = XCVR_EXTERNAL;
- et_cmd->port = PORT_FIBRE;
- et_cmd->supported = SUPPORTED_FIBRE;
- et_cmd->advertising = ADVERTISED_FIBRE;
- et_cmd->phy_address = phy_index;
+ cmd->base.port = PORT_FIBRE;
+ supported = SUPPORTED_FIBRE;
+ advertising = ADVERTISED_FIBRE;
+ cmd->base.phy_address = phy_index;
} else {
- et_cmd->transceiver = XCVR_INTERNAL;
- et_cmd->supported = SUPPORTED_10000baseT_Full;
- et_cmd->advertising = ADVERTISED_10000baseT_Full;
- et_cmd->phy_address = mac_index;
+ supported = SUPPORTED_10000baseT_Full;
+ advertising = ADVERTISED_10000baseT_Full;
+ cmd->base.phy_address = mac_index;
}
- ethtool_cmd_speed_set(et_cmd, SPEED_10000);
- et_cmd->autoneg = AUTONEG_DISABLE;
+ cmd->base.speed = SPEED_10000;
+ cmd->base.autoneg = AUTONEG_DISABLE;
+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
+ supported);
+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
+ advertising);
+
return 0;
}
@@ -1525,7 +1535,9 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
/**
* nes_netdev_set_settings
*/
-static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd *et_cmd)
+static int
+nes_netdev_set_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
@@ -1539,7 +1551,7 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
spin_lock_irqsave(&nesadapter->phy_lock, flags);
nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
- if (et_cmd->autoneg) {
+ if (cmd->base.autoneg) {
/* Turn on Full duplex, Autoneg, and restart autonegotiation */
phy_data |= 0x1300;
} else {
@@ -1556,8 +1568,6 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
static const struct ethtool_ops nes_ethtool_ops = {
.get_link = ethtool_op_get_link,
- .get_settings = nes_netdev_get_settings,
- .set_settings = nes_netdev_set_settings,
.get_strings = nes_netdev_get_strings,
.get_sset_count = nes_netdev_get_sset_count,
.get_ethtool_stats = nes_netdev_get_ethtool_stats,
@@ -1566,6 +1576,8 @@ static const struct ethtool_ops nes_ethtool_ops = {
.set_coalesce = nes_netdev_set_coalesce,
.get_pauseparam = nes_netdev_get_pauseparam,
.set_pauseparam = nes_netdev_set_pauseparam,
+ .get_link_ksettings = nes_netdev_get_link_ksettings,
+ .set_link_ksettings = nes_netdev_set_link_ksettings,
};
static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, netdev_features_t features)
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index bd69125731c1..aff9fb14768b 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -771,7 +771,8 @@ static int nes_dealloc_pd(struct ib_pd *ibpd)
/**
* nes_create_ah
*/
-static struct ib_ah *nes_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
+static struct ib_ah *nes_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
{
return ERR_PTR(-ENOSYS);
}
@@ -1075,7 +1076,6 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
mem = kzalloc(sizeof(*nesqp)+NES_SW_CONTEXT_ALIGN-1, GFP_KERNEL);
if (!mem) {
nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
- nes_debug(NES_DBG_QP, "Unable to allocate QP\n");
return ERR_PTR(-ENOMEM);
}
u64nesqp = (unsigned long)mem;
@@ -1475,7 +1475,6 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev,
nescq = kzalloc(sizeof(struct nes_cq), GFP_KERNEL);
if (!nescq) {
nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
- nes_debug(NES_DBG_CQ, "Unable to allocate nes_cq struct\n");
return ERR_PTR(-ENOMEM);
}
@@ -2408,7 +2407,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
}
nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL);
if (!nespbl) {
- nes_debug(NES_DBG_MR, "Unable to allocate PBL\n");
ib_umem_release(region);
return ERR_PTR(-ENOMEM);
}
@@ -2416,7 +2414,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (!nesmr) {
ib_umem_release(region);
kfree(nespbl);
- nes_debug(NES_DBG_MR, "Unable to allocate nesmr\n");
return ERR_PTR(-ENOMEM);
}
nesmr->region = region;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
index 797362a297b2..14d33b0f3950 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
@@ -154,7 +154,8 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
return status;
}
-struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
+struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr,
+ struct ib_udata *udata)
{
u32 *ahid_addr;
int status;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.h b/drivers/infiniband/hw/ocrdma/ocrdma_ah.h
index 3856dd4c7e3d..0704a24b17c8 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.h
@@ -50,7 +50,9 @@ enum {
OCRDMA_AH_L3_TYPE_MASK = 0x03,
OCRDMA_AH_L3_TYPE_SHIFT = 0x1D /* 29 bits */
};
-struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *);
+
+struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *,
+ struct ib_udata *);
int ocrdma_destroy_ah(struct ib_ah *);
int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *);
int ocrdma_modify_ah(struct ib_ah *, struct ib_ah_attr *);
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
index 67fc0b6857e1..9a305201545e 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
@@ -1596,10 +1596,9 @@ void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev)
dev->pd_mgr = kzalloc(sizeof(struct ocrdma_pd_resource_mgr),
GFP_KERNEL);
- if (!dev->pd_mgr) {
- pr_err("%s(%d)Memory allocation failure.\n", __func__, dev->id);
+ if (!dev->pd_mgr)
return;
- }
+
status = ocrdma_mbx_alloc_pd_range(dev);
if (status) {
pr_err("%s(%d) Unable to initialize PD pool, using default.\n",
@@ -1642,7 +1641,7 @@ static int ocrdma_build_q_conf(u32 *num_entries, int entry_size,
static int ocrdma_mbx_create_ah_tbl(struct ocrdma_dev *dev)
{
int i;
- int status = 0;
+ int status = -ENOMEM;
int max_ah;
struct ocrdma_create_ah_tbl *cmd;
struct ocrdma_create_ah_tbl_rsp *rsp;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
index 8bef09a8c49f..f8e4b0a6486f 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_stats.c
@@ -84,10 +84,8 @@ bool ocrdma_alloc_stats_resources(struct ocrdma_dev *dev)
/* Alloc debugfs mem */
mem->debugfs_mem = kzalloc(OCRDMA_MAX_DBGFS_MEM, GFP_KERNEL);
- if (!mem->debugfs_mem) {
- pr_err("%s: stats debugfs mem allocation failed\n", __func__);
+ if (!mem->debugfs_mem)
return false;
- }
return true;
}
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index a61514296767..302fb05e6e6f 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -511,8 +511,10 @@ int qedr_dealloc_pd(struct ib_pd *ibpd)
struct qedr_dev *dev = get_qedr_dev(ibpd->device);
struct qedr_pd *pd = get_qedr_pd(ibpd);
- if (!pd)
+ if (!pd) {
pr_err("Invalid PD received in dealloc_pd\n");
+ return -EINVAL;
+ }
DP_DEBUG(dev, QEDR_MSG_INIT, "Deallocating PD %d\n", pd->pd_id);
dev->ops->rdma_dealloc_pd(dev->rdma_ctx, pd->pd_id);
@@ -1477,6 +1479,7 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd,
struct qedr_ucontext *ctx = NULL;
struct qedr_create_qp_ureq ureq;
struct qedr_qp *qp;
+ struct ib_qp *ibqp;
int rc = 0;
DP_DEBUG(dev, QEDR_MSG_QP, "create qp: called from %s, pd=%p\n",
@@ -1486,13 +1489,13 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd,
if (rc)
return ERR_PTR(rc);
+ if (attrs->srq)
+ return ERR_PTR(-EINVAL);
+
qp = kzalloc(sizeof(*qp), GFP_KERNEL);
if (!qp)
return ERR_PTR(-ENOMEM);
- if (attrs->srq)
- return ERR_PTR(-EINVAL);
-
DP_DEBUG(dev, QEDR_MSG_QP,
"create qp: sq_cq=%p, sq_icid=%d, rq_cq=%p, rq_icid=%d\n",
get_qedr_cq(attrs->send_cq),
@@ -1508,7 +1511,10 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd,
"create qp: unexpected udata when creating GSI QP\n");
goto err0;
}
- return qedr_create_gsi_qp(dev, attrs, qp);
+ ibqp = qedr_create_gsi_qp(dev, attrs, qp);
+ if (IS_ERR(ibqp))
+ kfree(qp);
+ return ibqp;
}
memset(&in_params, 0, sizeof(in_params));
@@ -2094,7 +2100,8 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
return rc;
}
-struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
+struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr,
+ struct ib_udata *udata)
{
struct qedr_ah *ah;
@@ -2413,8 +2420,7 @@ static void handle_completed_mrs(struct qedr_dev *dev, struct mr_info *info)
*/
pbl = list_first_entry(&info->inuse_pbl_list,
struct qedr_pbl, list_entry);
- list_del(&pbl->list_entry);
- list_add_tail(&pbl->list_entry, &info->free_pbl_list);
+ list_move_tail(&pbl->list_entry, &info->free_pbl_list);
info->completed_handled++;
}
}
@@ -2981,11 +2987,6 @@ int qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
return -EINVAL;
}
- if (!wr) {
- DP_ERR(dev, "Got an empty post send.\n");
- return -EINVAL;
- }
-
while (wr) {
rc = __qedr_post_send(ibqp, wr, bad_wr);
if (rc)
diff --git a/drivers/infiniband/hw/qedr/verbs.h b/drivers/infiniband/hw/qedr/verbs.h
index a9b5e67bb81e..070677ca4d19 100644
--- a/drivers/infiniband/hw/qedr/verbs.h
+++ b/drivers/infiniband/hw/qedr/verbs.h
@@ -70,7 +70,8 @@ int qedr_query_qp(struct ib_qp *, struct ib_qp_attr *qp_attr,
int qp_attr_mask, struct ib_qp_init_attr *);
int qedr_destroy_qp(struct ib_qp *ibqp);
-struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr);
+struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr,
+ struct ib_udata *udata);
int qedr_destroy_ah(struct ib_ah *ibah);
int qedr_dereg_mr(struct ib_mr *);
diff --git a/drivers/infiniband/hw/qib/qib_diag.c b/drivers/infiniband/hw/qib/qib_diag.c
index 8c34b23e5bf6..775018b32b0d 100644
--- a/drivers/infiniband/hw/qib/qib_diag.c
+++ b/drivers/infiniband/hw/qib/qib_diag.c
@@ -609,8 +609,6 @@ static ssize_t qib_diagpkt_write(struct file *fp,
tmpbuf = vmalloc(plen);
if (!tmpbuf) {
- qib_devinfo(dd->pcidev,
- "Unable to allocate tmp buffer, failing\n");
ret = -ENOMEM;
goto bail;
}
@@ -702,10 +700,8 @@ int qib_register_observer(struct qib_devdata *dd,
if (!dd || !op)
return -EINVAL;
olp = vmalloc(sizeof(*olp));
- if (!olp) {
- pr_err("vmalloc for observer failed\n");
+ if (!olp)
return -ENOMEM;
- }
spin_lock_irqsave(&dd->qib_diag_trans_lock, flags);
olp->op = op;
diff --git a/drivers/infiniband/hw/qib/qib_driver.c b/drivers/infiniband/hw/qib/qib_driver.c
index 728e0a030d2e..2b5982f743ef 100644
--- a/drivers/infiniband/hw/qib/qib_driver.c
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -420,8 +420,7 @@ static u32 qib_rcv_hdrerr(struct qib_ctxtdata *rcd, struct qib_pportdata *ppd,
if (list_empty(&qp->rspwait)) {
qp->r_flags |=
RVT_R_RSP_NAK;
- atomic_inc(
- &qp->refcount);
+ rvt_get_qp(qp);
list_add_tail(
&qp->rspwait,
&rcd->qp_wait_list);
diff --git a/drivers/infiniband/hw/qib/qib_eeprom.c b/drivers/infiniband/hw/qib/qib_eeprom.c
index 311ee6c3dd5e..33a2e74c8495 100644
--- a/drivers/infiniband/hw/qib/qib_eeprom.c
+++ b/drivers/infiniband/hw/qib/qib_eeprom.c
@@ -182,12 +182,8 @@ void qib_get_eeprom_info(struct qib_devdata *dd)
* */
len = sizeof(struct qib_flash);
buf = vmalloc(len);
- if (!buf) {
- qib_dev_err(dd,
- "Couldn't allocate memory to read %u bytes from eeprom for GUID\n",
- len);
+ if (!buf)
goto bail;
- }
/*
* Use "public" eeprom read function, which does locking and
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c
index 382466a90da7..2d1eacf1dfed 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -2066,8 +2066,11 @@ static ssize_t qib_write(struct file *fp, const char __user *data,
ssize_t ret = 0;
void *dest;
- if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
+ if (!ib_safe_file_access(fp)) {
+ pr_err_once("qib_write: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n",
+ task_tgid_vnr(current), current->comm);
return -EACCES;
+ }
if (count < sizeof(cmd.type)) {
ret = -EINVAL;
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
index a3733f25280f..92399d3ffd15 100644
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -1759,9 +1759,7 @@ static void pe_boardname(struct qib_devdata *dd)
}
namelen = strlen(n) + 1;
dd->boardname = kmalloc(namelen, GFP_KERNEL);
- if (!dd->boardname)
- qib_dev_err(dd, "Failed allocation for board name: %s\n", n);
- else
+ if (dd->boardname)
snprintf(dd->boardname, namelen, "%s", n);
if (dd->majrev != 4 || !dd->minrev || dd->minrev > 2)
@@ -2533,8 +2531,6 @@ static void init_6120_cntrnames(struct qib_devdata *dd)
dd->cspec->cntrnamelen = 1 + s - cntr6120names;
dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs
* sizeof(u64), GFP_KERNEL);
- if (!dd->cspec->cntrs)
- qib_dev_err(dd, "Failed allocation for counters\n");
for (i = 0, s = (char *)portcntr6120names; s; i++)
s = strchr(s + 1, '\n');
@@ -2542,8 +2538,6 @@ static void init_6120_cntrnames(struct qib_devdata *dd)
dd->cspec->portcntrnamelen = sizeof(portcntr6120names) - 1;
dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs
* sizeof(u64), GFP_KERNEL);
- if (!dd->cspec->portcntrs)
- qib_dev_err(dd, "Failed allocation for portcounters\n");
}
static u32 qib_read_6120cntrs(struct qib_devdata *dd, loff_t pos, char **namep,
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
index 00b2af211157..e55e31a69195 100644
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
@@ -2070,9 +2070,7 @@ static void qib_7220_boardname(struct qib_devdata *dd)
namelen = strlen(n) + 1;
dd->boardname = kmalloc(namelen, GFP_KERNEL);
- if (!dd->boardname)
- qib_dev_err(dd, "Failed allocation for board name: %s\n", n);
- else
+ if (dd->boardname)
snprintf(dd->boardname, namelen, "%s", n);
if (dd->majrev != 5 || !dd->minrev || dd->minrev > 2)
@@ -3179,8 +3177,6 @@ static void init_7220_cntrnames(struct qib_devdata *dd)
dd->cspec->cntrnamelen = 1 + s - cntr7220names;
dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs
* sizeof(u64), GFP_KERNEL);
- if (!dd->cspec->cntrs)
- qib_dev_err(dd, "Failed allocation for counters\n");
for (i = 0, s = (char *)portcntr7220names; s; i++)
s = strchr(s + 1, '\n');
@@ -3188,8 +3184,6 @@ static void init_7220_cntrnames(struct qib_devdata *dd)
dd->cspec->portcntrnamelen = sizeof(portcntr7220names) - 1;
dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs
* sizeof(u64), GFP_KERNEL);
- if (!dd->cspec->portcntrs)
- qib_dev_err(dd, "Failed allocation for portcounters\n");
}
static u32 qib_read_7220cntrs(struct qib_devdata *dd, loff_t pos, char **namep,
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index ded27172320e..c4a3616062f1 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -3627,9 +3627,7 @@ static unsigned qib_7322_boardname(struct qib_devdata *dd)
namelen = strlen(n) + 1;
dd->boardname = kmalloc(namelen, GFP_KERNEL);
- if (!dd->boardname)
- qib_dev_err(dd, "Failed allocation for board name: %s\n", n);
- else
+ if (dd->boardname)
snprintf(dd->boardname, namelen, "%s", n);
snprintf(dd->boardversion, sizeof(dd->boardversion),
@@ -3656,7 +3654,7 @@ static unsigned qib_7322_boardname(struct qib_devdata *dd)
static int qib_do_7322_reset(struct qib_devdata *dd)
{
u64 val;
- u64 *msix_vecsave;
+ u64 *msix_vecsave = NULL;
int i, msix_entries, ret = 1;
u16 cmdval;
u8 int_line, clinesz;
@@ -3677,10 +3675,7 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
/* can be up to 512 bytes, too big for stack */
msix_vecsave = kmalloc(2 * dd->cspec->num_msix_entries *
sizeof(u64), GFP_KERNEL);
- if (!msix_vecsave)
- qib_dev_err(dd, "No mem to save MSIx data\n");
- } else
- msix_vecsave = NULL;
+ }
/*
* Core PCI (as of 2.6.18) doesn't save or rewrite the full vector
@@ -5043,8 +5038,6 @@ static void init_7322_cntrnames(struct qib_devdata *dd)
dd->cspec->cntrnamelen = 1 + s - cntr7322names;
dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs
* sizeof(u64), GFP_KERNEL);
- if (!dd->cspec->cntrs)
- qib_dev_err(dd, "Failed allocation for counters\n");
for (i = 0, s = (char *)portcntr7322names; s; i++)
s = strchr(s + 1, '\n');
@@ -5053,9 +5046,6 @@ static void init_7322_cntrnames(struct qib_devdata *dd)
for (i = 0; i < dd->num_pports; ++i) {
dd->pport[i].cpspec->portcntrs = kmalloc(dd->cspec->nportcntrs
* sizeof(u64), GFP_KERNEL);
- if (!dd->pport[i].cpspec->portcntrs)
- qib_dev_err(dd,
- "Failed allocation for portcounters\n");
}
}
@@ -6461,7 +6451,6 @@ static int qib_init_7322_variables(struct qib_devdata *dd)
sizeof(*dd->cspec->sendibchk), GFP_KERNEL);
if (!dd->cspec->sendchkenable || !dd->cspec->sendgrhchk ||
!dd->cspec->sendibchk) {
- qib_dev_err(dd, "Failed allocation for hdrchk bitmaps\n");
ret = -ENOMEM;
goto bail;
}
@@ -7338,10 +7327,9 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev,
tabsize = actual_cnt;
dd->cspec->msix_entries = kzalloc(tabsize *
sizeof(struct qib_msix_entry), GFP_KERNEL);
- if (!dd->cspec->msix_entries) {
- qib_dev_err(dd, "No memory for MSIx table\n");
+ if (!dd->cspec->msix_entries)
tabsize = 0;
- }
+
for (i = 0; i < tabsize; i++)
dd->cspec->msix_entries[i].msix.entry = i;
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index 1730aa839a47..b50240b1d5a4 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -133,11 +133,8 @@ int qib_create_ctxts(struct qib_devdata *dd)
* cleanup iterates across all possible ctxts.
*/
dd->rcd = kcalloc(dd->ctxtcnt, sizeof(*dd->rcd), GFP_KERNEL);
- if (!dd->rcd) {
- qib_dev_err(dd,
- "Unable to allocate ctxtdata array, failing\n");
+ if (!dd->rcd)
return -ENOMEM;
- }
/* create (one or more) kctxt */
for (i = 0; i < dd->first_user_ctxt; ++i) {
@@ -265,39 +262,23 @@ int qib_init_pportdata(struct qib_pportdata *ppd, struct qib_devdata *dd,
size = IB_CC_TABLE_CAP_DEFAULT * sizeof(struct ib_cc_table_entry)
* IB_CCT_ENTRIES;
ppd->ccti_entries = kzalloc(size, GFP_KERNEL);
- if (!ppd->ccti_entries) {
- qib_dev_err(dd,
- "failed to allocate congestion control table for port %d!\n",
- port);
+ if (!ppd->ccti_entries)
goto bail;
- }
size = IB_CC_CCS_ENTRIES * sizeof(struct ib_cc_congestion_entry);
ppd->congestion_entries = kzalloc(size, GFP_KERNEL);
- if (!ppd->congestion_entries) {
- qib_dev_err(dd,
- "failed to allocate congestion setting list for port %d!\n",
- port);
+ if (!ppd->congestion_entries)
goto bail_1;
- }
size = sizeof(struct cc_table_shadow);
ppd->ccti_entries_shadow = kzalloc(size, GFP_KERNEL);
- if (!ppd->ccti_entries_shadow) {
- qib_dev_err(dd,
- "failed to allocate shadow ccti list for port %d!\n",
- port);
+ if (!ppd->ccti_entries_shadow)
goto bail_2;
- }
size = sizeof(struct ib_cc_congestion_setting_attr);
ppd->congestion_entries_shadow = kzalloc(size, GFP_KERNEL);
- if (!ppd->congestion_entries_shadow) {
- qib_dev_err(dd,
- "failed to allocate shadow congestion setting list for port %d!\n",
- port);
+ if (!ppd->congestion_entries_shadow)
goto bail_3;
- }
return 0;
@@ -391,18 +372,12 @@ static void init_shadow_tids(struct qib_devdata *dd)
dma_addr_t *addrs;
pages = vzalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *));
- if (!pages) {
- qib_dev_err(dd,
- "failed to allocate shadow page * array, no expected sends!\n");
+ if (!pages)
goto bail;
- }
addrs = vzalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t));
- if (!addrs) {
- qib_dev_err(dd,
- "failed to allocate shadow dma handle array, no expected sends!\n");
+ if (!addrs)
goto bail_free;
- }
dd->pageshadow = pages;
dd->physshadow = addrs;
@@ -1026,11 +1001,8 @@ static void qib_verify_pioperf(struct qib_devdata *dd)
cnt = 1024;
addr = vmalloc(cnt);
- if (!addr) {
- qib_devinfo(dd->pcidev,
- "Couldn't get memory for checking PIO perf, skipping\n");
+ if (!addr)
goto done;
- }
preempt_disable(); /* we want reasonably accurate elapsed time */
msecs = 1 + jiffies_to_msecs(jiffies);
@@ -1172,9 +1144,6 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
sizeof(long), GFP_KERNEL);
if (qib_cpulist)
qib_cpulist_count = count;
- else
- qib_early_err(&pdev->dev,
- "Could not alloc cpulist info, cpu affinity might be wrong\n");
}
#ifdef CONFIG_DEBUG_FS
qib_dbg_ibdev_init(&dd->verbs_dev);
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index 2097512e75aa..031433cb7206 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -941,8 +941,6 @@ void qib_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
{
struct ib_other_headers *ohdr;
struct rvt_swqe *wqe;
- struct ib_wc wc;
- unsigned i;
u32 opcode;
u32 psn;
@@ -988,22 +986,8 @@ void qib_rc_send_complete(struct rvt_qp *qp, struct ib_header *hdr)
qp->s_last = s_last;
/* see post_send() */
barrier();
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
-
- rvt_put_mr(sge->mr);
- }
- /* Post a send completion queue entry if requested. */
- if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
- (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
- memset(&wc, 0, sizeof(wc));
- wc.wr_id = wqe->wr.wr_id;
- wc.status = IB_WC_SUCCESS;
- wc.opcode = ib_qib_wc_opcode[wqe->wr.opcode];
- wc.byte_len = wqe->length;
- wc.qp = &qp->ibqp;
- rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
- }
+ rvt_put_swqe(wqe);
+ rvt_qp_swqe_complete(qp, wqe, IB_WC_SUCCESS);
}
/*
* If we were waiting for sends to complete before resending,
@@ -1032,9 +1016,6 @@ static struct rvt_swqe *do_rc_completion(struct rvt_qp *qp,
struct rvt_swqe *wqe,
struct qib_ibport *ibp)
{
- struct ib_wc wc;
- unsigned i;
-
/*
* Don't decrement refcount and don't generate a
* completion if the SWQE is being resent until the send
@@ -1044,28 +1025,14 @@ static struct rvt_swqe *do_rc_completion(struct rvt_qp *qp,
qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) > 0) {
u32 s_last;
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
-
- rvt_put_mr(sge->mr);
- }
+ rvt_put_swqe(wqe);
s_last = qp->s_last;
if (++s_last >= qp->s_size)
s_last = 0;
qp->s_last = s_last;
/* see post_send() */
barrier();
- /* Post a send completion queue entry if requested. */
- if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
- (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
- memset(&wc, 0, sizeof(wc));
- wc.wr_id = wqe->wr.wr_id;
- wc.status = IB_WC_SUCCESS;
- wc.opcode = ib_qib_wc_opcode[wqe->wr.opcode];
- wc.byte_len = wqe->length;
- wc.qp = &qp->ibqp;
- rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
- }
+ rvt_qp_swqe_complete(qp, wqe, IB_WC_SUCCESS);
} else
this_cpu_inc(*ibp->rvp.rc_delayed_comp);
@@ -2112,8 +2079,7 @@ send_last:
* Update the next expected PSN. We add 1 later
* below, so only add the remainder here.
*/
- if (len > pmtu)
- qp->r_psn += (len - 1) / pmtu;
+ qp->r_psn += rvt_div_mtu(qp, len - 1);
} else {
e->rdma_sge.mr = NULL;
e->rdma_sge.vaddr = NULL;
diff --git a/drivers/infiniband/hw/qib/qib_ruc.c b/drivers/infiniband/hw/qib/qib_ruc.c
index de1bde5950f5..e54a2feeeb10 100644
--- a/drivers/infiniband/hw/qib/qib_ruc.c
+++ b/drivers/infiniband/hw/qib/qib_ruc.c
@@ -793,7 +793,6 @@ void qib_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
enum ib_wc_status status)
{
u32 old_last, last;
- unsigned i;
if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_OR_FLUSH_SEND))
return;
@@ -805,32 +804,13 @@ void qib_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
qp->s_last = last;
/* See post_send() */
barrier();
- for (i = 0; i < wqe->wr.num_sge; i++) {
- struct rvt_sge *sge = &wqe->sg_list[i];
-
- rvt_put_mr(sge->mr);
- }
+ rvt_put_swqe(wqe);
if (qp->ibqp.qp_type == IB_QPT_UD ||
qp->ibqp.qp_type == IB_QPT_SMI ||
qp->ibqp.qp_type == IB_QPT_GSI)
atomic_dec(&ibah_to_rvtah(wqe->ud_wr.ah)->refcount);
- /* See ch. 11.2.4.1 and 10.7.3.1 */
- if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
- (wqe->wr.send_flags & IB_SEND_SIGNALED) ||
- status != IB_WC_SUCCESS) {
- struct ib_wc wc;
-
- memset(&wc, 0, sizeof(wc));
- wc.wr_id = wqe->wr.wr_id;
- wc.status = status;
- wc.opcode = ib_qib_wc_opcode[wqe->wr.opcode];
- wc.qp = &qp->ibqp;
- if (status == IB_WC_SUCCESS)
- wc.byte_len = wqe->length;
- rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc,
- status != IB_WC_SUCCESS);
- }
+ rvt_qp_swqe_complete(qp, wqe, status);
if (qp->s_acked == old_last)
qp->s_acked = last;
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index 954f15064514..4b54c0ddd08a 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -114,19 +114,6 @@ module_param_named(disable_sma, ib_qib_disable_sma, uint, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(disable_sma, "Disable the SMA");
/*
- * Translate ib_wr_opcode into ib_wc_opcode.
- */
-const enum ib_wc_opcode ib_qib_wc_opcode[] = {
- [IB_WR_RDMA_WRITE] = IB_WC_RDMA_WRITE,
- [IB_WR_RDMA_WRITE_WITH_IMM] = IB_WC_RDMA_WRITE,
- [IB_WR_SEND] = IB_WC_SEND,
- [IB_WR_SEND_WITH_IMM] = IB_WC_SEND,
- [IB_WR_RDMA_READ] = IB_WC_RDMA_READ,
- [IB_WR_ATOMIC_CMP_AND_SWP] = IB_WC_COMP_SWAP,
- [IB_WR_ATOMIC_FETCH_AND_ADD] = IB_WC_FETCH_ADD
-};
-
-/*
* System image GUID.
*/
__be64 ib_qib_sys_image_guid;
@@ -464,7 +451,7 @@ static void mem_timer(unsigned long data)
priv = list_entry(list->next, struct qib_qp_priv, iowait);
qp = priv->owner;
list_del_init(&priv->iowait);
- atomic_inc(&qp->refcount);
+ rvt_get_qp(qp);
if (!list_empty(list))
mod_timer(&dev->mem_timer, jiffies + 1);
}
@@ -477,8 +464,7 @@ static void mem_timer(unsigned long data)
qib_schedule_send(qp);
}
spin_unlock_irqrestore(&qp->s_lock, flags);
- if (atomic_dec_and_test(&qp->refcount))
- wake_up(&qp->wait);
+ rvt_put_qp(qp);
}
}
@@ -762,7 +748,7 @@ void qib_put_txreq(struct qib_verbs_txreq *tx)
iowait);
qp = priv->owner;
list_del_init(&priv->iowait);
- atomic_inc(&qp->refcount);
+ rvt_get_qp(qp);
spin_unlock_irqrestore(&dev->rdi.pending_lock, flags);
spin_lock_irqsave(&qp->s_lock, flags);
@@ -772,8 +758,7 @@ void qib_put_txreq(struct qib_verbs_txreq *tx)
}
spin_unlock_irqrestore(&qp->s_lock, flags);
- if (atomic_dec_and_test(&qp->refcount))
- wake_up(&qp->wait);
+ rvt_put_qp(qp);
} else
spin_unlock_irqrestore(&dev->rdi.pending_lock, flags);
}
@@ -808,7 +793,7 @@ void qib_verbs_sdma_desc_avail(struct qib_pportdata *ppd, unsigned avail)
break;
avail -= qpp->s_tx->txreq.sg_count;
list_del_init(&qpp->iowait);
- atomic_inc(&qp->refcount);
+ rvt_get_qp(qp);
qps[n++] = qp;
}
@@ -822,8 +807,7 @@ void qib_verbs_sdma_desc_avail(struct qib_pportdata *ppd, unsigned avail)
qib_schedule_send(qp);
}
spin_unlock(&qp->s_lock);
- if (atomic_dec_and_test(&qp->refcount))
- wake_up(&qp->wait);
+ rvt_put_qp(qp);
}
}
@@ -1288,7 +1272,7 @@ void qib_ib_piobufavail(struct qib_devdata *dd)
priv = list_entry(list->next, struct qib_qp_priv, iowait);
qp = priv->owner;
list_del_init(&priv->iowait);
- atomic_inc(&qp->refcount);
+ rvt_get_qp(qp);
qps[n++] = qp;
}
dd->f_wantpiobuf_intr(dd, 0);
@@ -1306,8 +1290,7 @@ full:
spin_unlock_irqrestore(&qp->s_lock, flags);
/* Notify qib_destroy_qp() if it is waiting. */
- if (atomic_dec_and_test(&qp->refcount))
- wake_up(&qp->wait);
+ rvt_put_qp(qp);
}
}
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
index 5b0248adf4ce..092d4e11a633 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
@@ -117,10 +117,10 @@ static int enable_qp_grp(struct usnic_ib_qp_grp *qp_grp)
vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
res_chunk = get_qp_res_chunk(qp_grp);
- if (IS_ERR_OR_NULL(res_chunk)) {
+ if (IS_ERR(res_chunk)) {
usnic_err("Unable to get qp res with err %ld\n",
PTR_ERR(res_chunk));
- return res_chunk ? PTR_ERR(res_chunk) : -ENOMEM;
+ return PTR_ERR(res_chunk);
}
for (i = 0; i < res_chunk->cnt; i++) {
@@ -158,10 +158,10 @@ static int disable_qp_grp(struct usnic_ib_qp_grp *qp_grp)
vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
res_chunk = get_qp_res_chunk(qp_grp);
- if (IS_ERR_OR_NULL(res_chunk)) {
+ if (IS_ERR(res_chunk)) {
usnic_err("Unable to get qp res with err %ld\n",
PTR_ERR(res_chunk));
- return res_chunk ? PTR_ERR(res_chunk) : -ENOMEM;
+ return PTR_ERR(res_chunk);
}
for (i = 0; i < res_chunk->cnt; i++) {
@@ -186,11 +186,11 @@ static int init_filter_action(struct usnic_ib_qp_grp *qp_grp,
struct usnic_vnic_res_chunk *res_chunk;
res_chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_RQ);
- if (IS_ERR_OR_NULL(res_chunk)) {
+ if (IS_ERR(res_chunk)) {
usnic_err("Unable to get %s with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_RQ),
PTR_ERR(res_chunk));
- return res_chunk ? PTR_ERR(res_chunk) : -ENOMEM;
+ return PTR_ERR(res_chunk);
}
uaction->vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
@@ -228,8 +228,6 @@ create_roce_custom_flow(struct usnic_ib_qp_grp *qp_grp,
flow = usnic_fwd_alloc_flow(qp_grp->ufdev, &filter, &uaction);
if (IS_ERR_OR_NULL(flow)) {
- usnic_err("Unable to alloc flow failed with err %ld\n",
- PTR_ERR(flow));
err = flow ? PTR_ERR(flow) : -EFAULT;
goto out_unreserve_port;
}
@@ -303,8 +301,6 @@ create_udp_flow(struct usnic_ib_qp_grp *qp_grp,
flow = usnic_fwd_alloc_flow(qp_grp->ufdev, &filter, &uaction);
if (IS_ERR_OR_NULL(flow)) {
- usnic_err("Unable to alloc flow failed with err %ld\n",
- PTR_ERR(flow));
err = flow ? PTR_ERR(flow) : -EFAULT;
goto out_put_sock;
}
@@ -694,18 +690,14 @@ usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf,
}
qp_grp = kzalloc(sizeof(*qp_grp), GFP_ATOMIC);
- if (!qp_grp) {
- usnic_err("Unable to alloc qp_grp - Out of memory\n");
+ if (!qp_grp)
return NULL;
- }
qp_grp->res_chunk_list = alloc_res_chunk_list(vf->vnic, res_spec,
qp_grp);
if (IS_ERR_OR_NULL(qp_grp->res_chunk_list)) {
err = qp_grp->res_chunk_list ?
PTR_ERR(qp_grp->res_chunk_list) : -ENOMEM;
- usnic_err("Unable to alloc res for %d with err %d\n",
- qp_grp->grp_id, err);
goto out_free_qp_grp;
}
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
index a5bfbba6bbac..74819a7951e2 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -87,12 +87,12 @@ static int usnic_ib_fill_create_qp_resp(struct usnic_ib_qp_grp *qp_grp,
resp.bar_len = bar->len;
chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_RQ);
- if (IS_ERR_OR_NULL(chunk)) {
+ if (IS_ERR(chunk)) {
usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_RQ),
qp_grp->grp_id,
PTR_ERR(chunk));
- return chunk ? PTR_ERR(chunk) : -ENOMEM;
+ return PTR_ERR(chunk);
}
WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_RQ);
@@ -101,12 +101,12 @@ static int usnic_ib_fill_create_qp_resp(struct usnic_ib_qp_grp *qp_grp,
resp.rq_idx[i] = chunk->res[i]->vnic_idx;
chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_WQ);
- if (IS_ERR_OR_NULL(chunk)) {
+ if (IS_ERR(chunk)) {
usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_WQ),
qp_grp->grp_id,
PTR_ERR(chunk));
- return chunk ? PTR_ERR(chunk) : -ENOMEM;
+ return PTR_ERR(chunk);
}
WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_WQ);
@@ -115,12 +115,12 @@ static int usnic_ib_fill_create_qp_resp(struct usnic_ib_qp_grp *qp_grp,
resp.wq_idx[i] = chunk->res[i]->vnic_idx;
chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_CQ);
- if (IS_ERR_OR_NULL(chunk)) {
+ if (IS_ERR(chunk)) {
usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_CQ),
qp_grp->grp_id,
PTR_ERR(chunk));
- return chunk ? PTR_ERR(chunk) : -ENOMEM;
+ return PTR_ERR(chunk);
}
WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_CQ);
@@ -738,7 +738,9 @@ int usnic_ib_mmap(struct ib_ucontext *context,
/* In ib callbacks section - Start of stub funcs */
struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
- struct ib_ah_attr *ah_attr)
+ struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
+
{
usnic_dbg("\n");
return ERR_PTR(-EPERM);
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
index 0d9d2e6a14d5..0ed8e072329e 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
@@ -75,7 +75,9 @@ int usnic_ib_dealloc_ucontext(struct ib_ucontext *ibcontext);
int usnic_ib_mmap(struct ib_ucontext *context,
struct vm_area_struct *vma);
struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
- struct ib_ah_attr *ah_attr);
+ struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata);
+
int usnic_ib_destroy_ah(struct ib_ah *ah);
int usnic_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
struct ib_send_wr **bad_wr);
diff --git a/drivers/infiniband/hw/usnic/usnic_vnic.c b/drivers/infiniband/hw/usnic/usnic_vnic.c
index 887510718690..e7b0030254da 100644
--- a/drivers/infiniband/hw/usnic/usnic_vnic.c
+++ b/drivers/infiniband/hw/usnic/usnic_vnic.c
@@ -241,17 +241,12 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
return ERR_PTR(-EINVAL);
ret = kzalloc(sizeof(*ret), GFP_ATOMIC);
- if (!ret) {
- usnic_err("Failed to allocate chunk for %s - Out of memory\n",
- usnic_vnic_pci_name(vnic));
+ if (!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);
}
@@ -311,8 +306,10 @@ static int usnic_vnic_alloc_res_chunk(struct usnic_vnic *vnic,
struct usnic_vnic_res *res;
cnt = vnic_dev_get_res_count(vnic->vdev, _to_vnic_res_type(type));
- if (cnt < 1)
+ if (cnt < 1) {
+ usnic_err("Wrong res count with cnt %d\n", cnt);
return -EINVAL;
+ }
chunk->cnt = chunk->free_cnt = cnt;
chunk->res = kzalloc(sizeof(*(chunk->res))*cnt, GFP_KERNEL);
@@ -384,12 +381,8 @@ static int usnic_vnic_discover_resources(struct pci_dev *pdev,
res_type < USNIC_VNIC_RES_TYPE_MAX; res_type++) {
err = usnic_vnic_alloc_res_chunk(vnic, res_type,
&vnic->chunks[res_type]);
- if (err) {
- usnic_err("Failed to alloc res %s with err %d\n",
- usnic_vnic_res_type_to_str(res_type),
- err);
+ if (err)
goto out_clean_chunks;
- }
}
return 0;
@@ -454,11 +447,8 @@ struct usnic_vnic *usnic_vnic_alloc(struct pci_dev *pdev)
}
vnic = kzalloc(sizeof(*vnic), GFP_KERNEL);
- if (!vnic) {
- usnic_err("Failed to alloc vnic for %s - out of memory\n",
- pci_name(pdev));
+ if (!vnic)
return ERR_PTR(-ENOMEM);
- }
spin_lock_init(&vnic->res_lock);
diff --git a/drivers/infiniband/hw/vmw_pvrdma/Kconfig b/drivers/infiniband/hw/vmw_pvrdma/Kconfig
new file mode 100644
index 000000000000..5a9790ac0ede
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/Kconfig
@@ -0,0 +1,7 @@
+config INFINIBAND_VMWARE_PVRDMA
+ tristate "VMware Paravirtualized RDMA Driver"
+ depends on NETDEVICES && ETHERNET && PCI && INET && VMXNET3
+ ---help---
+ This driver provides low-level support for VMware Paravirtual
+ RDMA adapter. It interacts with the VMXNet3 driver to provide
+ Ethernet capabilities.
diff --git a/drivers/infiniband/hw/vmw_pvrdma/Makefile b/drivers/infiniband/hw/vmw_pvrdma/Makefile
new file mode 100644
index 000000000000..0194ed19f542
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_INFINIBAND_VMWARE_PVRDMA) += vmw_pvrdma.o
+
+vmw_pvrdma-y := pvrdma_cmd.o pvrdma_cq.o pvrdma_doorbell.o pvrdma_main.o pvrdma_misc.o pvrdma_mr.o pvrdma_qp.o pvrdma_verbs.o
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
new file mode 100644
index 000000000000..71e1d55d69d6
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PVRDMA_H__
+#define __PVRDMA_H__
+
+#include <linux/compiler.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <rdma/ib_umem.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/vmw_pvrdma-abi.h>
+
+#include "pvrdma_ring.h"
+#include "pvrdma_dev_api.h"
+#include "pvrdma_verbs.h"
+
+/* NOT the same as BIT_MASK(). */
+#define PVRDMA_MASK(n) ((n << 1) - 1)
+
+/*
+ * VMware PVRDMA PCI device id.
+ */
+#define PCI_DEVICE_ID_VMWARE_PVRDMA 0x0820
+
+struct pvrdma_dev;
+
+struct pvrdma_page_dir {
+ dma_addr_t dir_dma;
+ u64 *dir;
+ int ntables;
+ u64 **tables;
+ u64 npages;
+ void **pages;
+};
+
+struct pvrdma_cq {
+ struct ib_cq ibcq;
+ int offset;
+ spinlock_t cq_lock; /* Poll lock. */
+ struct pvrdma_uar_map *uar;
+ struct ib_umem *umem;
+ struct pvrdma_ring_state *ring_state;
+ struct pvrdma_page_dir pdir;
+ u32 cq_handle;
+ bool is_kernel;
+ atomic_t refcnt;
+ wait_queue_head_t wait;
+};
+
+struct pvrdma_id_table {
+ u32 last;
+ u32 top;
+ u32 max;
+ u32 mask;
+ spinlock_t lock; /* Table lock. */
+ unsigned long *table;
+};
+
+struct pvrdma_uar_map {
+ unsigned long pfn;
+ void __iomem *map;
+ int index;
+};
+
+struct pvrdma_uar_table {
+ struct pvrdma_id_table tbl;
+ int size;
+};
+
+struct pvrdma_ucontext {
+ struct ib_ucontext ibucontext;
+ struct pvrdma_dev *dev;
+ struct pvrdma_uar_map uar;
+ u64 ctx_handle;
+};
+
+struct pvrdma_pd {
+ struct ib_pd ibpd;
+ u32 pdn;
+ u32 pd_handle;
+ int privileged;
+};
+
+struct pvrdma_mr {
+ u32 mr_handle;
+ u64 iova;
+ u64 size;
+};
+
+struct pvrdma_user_mr {
+ struct ib_mr ibmr;
+ struct ib_umem *umem;
+ struct pvrdma_mr mmr;
+ struct pvrdma_page_dir pdir;
+ u64 *pages;
+ u32 npages;
+ u32 max_pages;
+ u32 page_shift;
+};
+
+struct pvrdma_wq {
+ struct pvrdma_ring *ring;
+ spinlock_t lock; /* Work queue lock. */
+ int wqe_cnt;
+ int wqe_size;
+ int max_sg;
+ int offset;
+};
+
+struct pvrdma_ah {
+ struct ib_ah ibah;
+ struct pvrdma_av av;
+};
+
+struct pvrdma_qp {
+ struct ib_qp ibqp;
+ u32 qp_handle;
+ u32 qkey;
+ struct pvrdma_wq sq;
+ struct pvrdma_wq rq;
+ struct ib_umem *rumem;
+ struct ib_umem *sumem;
+ struct pvrdma_page_dir pdir;
+ int npages;
+ int npages_send;
+ int npages_recv;
+ u32 flags;
+ u8 port;
+ u8 state;
+ bool is_kernel;
+ struct mutex mutex; /* QP state mutex. */
+ atomic_t refcnt;
+ wait_queue_head_t wait;
+};
+
+struct pvrdma_dev {
+ /* PCI device-related information. */
+ struct ib_device ib_dev;
+ struct pci_dev *pdev;
+ void __iomem *regs;
+ struct pvrdma_device_shared_region *dsr; /* Shared region pointer */
+ dma_addr_t dsrbase; /* Shared region base address */
+ void *cmd_slot;
+ void *resp_slot;
+ unsigned long flags;
+ struct list_head device_link;
+
+ /* Locking and interrupt information. */
+ spinlock_t cmd_lock; /* Command lock. */
+ struct semaphore cmd_sema;
+ struct completion cmd_done;
+ struct {
+ enum pvrdma_intr_type type; /* Intr type */
+ struct msix_entry msix_entry[PVRDMA_MAX_INTERRUPTS];
+ irq_handler_t handler[PVRDMA_MAX_INTERRUPTS];
+ u8 enabled[PVRDMA_MAX_INTERRUPTS];
+ u8 size;
+ } intr;
+
+ /* RDMA-related device information. */
+ union ib_gid *sgid_tbl;
+ struct pvrdma_ring_state *async_ring_state;
+ struct pvrdma_page_dir async_pdir;
+ struct pvrdma_ring_state *cq_ring_state;
+ struct pvrdma_page_dir cq_pdir;
+ struct pvrdma_cq **cq_tbl;
+ spinlock_t cq_tbl_lock;
+ struct pvrdma_qp **qp_tbl;
+ spinlock_t qp_tbl_lock;
+ struct pvrdma_uar_table uar_table;
+ struct pvrdma_uar_map driver_uar;
+ __be64 sys_image_guid;
+ spinlock_t desc_lock; /* Device modification lock. */
+ u32 port_cap_mask;
+ struct mutex port_mutex; /* Port modification mutex. */
+ bool ib_active;
+ atomic_t num_qps;
+ atomic_t num_cqs;
+ atomic_t num_pds;
+ atomic_t num_ahs;
+
+ /* Network device information. */
+ struct net_device *netdev;
+ struct notifier_block nb_netdev;
+};
+
+struct pvrdma_netdevice_work {
+ struct work_struct work;
+ struct net_device *event_netdev;
+ unsigned long event;
+};
+
+static inline struct pvrdma_dev *to_vdev(struct ib_device *ibdev)
+{
+ return container_of(ibdev, struct pvrdma_dev, ib_dev);
+}
+
+static inline struct
+pvrdma_ucontext *to_vucontext(struct ib_ucontext *ibucontext)
+{
+ return container_of(ibucontext, struct pvrdma_ucontext, ibucontext);
+}
+
+static inline struct pvrdma_pd *to_vpd(struct ib_pd *ibpd)
+{
+ return container_of(ibpd, struct pvrdma_pd, ibpd);
+}
+
+static inline struct pvrdma_cq *to_vcq(struct ib_cq *ibcq)
+{
+ return container_of(ibcq, struct pvrdma_cq, ibcq);
+}
+
+static inline struct pvrdma_user_mr *to_vmr(struct ib_mr *ibmr)
+{
+ return container_of(ibmr, struct pvrdma_user_mr, ibmr);
+}
+
+static inline struct pvrdma_qp *to_vqp(struct ib_qp *ibqp)
+{
+ return container_of(ibqp, struct pvrdma_qp, ibqp);
+}
+
+static inline struct pvrdma_ah *to_vah(struct ib_ah *ibah)
+{
+ return container_of(ibah, struct pvrdma_ah, ibah);
+}
+
+static inline void pvrdma_write_reg(struct pvrdma_dev *dev, u32 reg, u32 val)
+{
+ writel(cpu_to_le32(val), dev->regs + reg);
+}
+
+static inline u32 pvrdma_read_reg(struct pvrdma_dev *dev, u32 reg)
+{
+ return le32_to_cpu(readl(dev->regs + reg));
+}
+
+static inline void pvrdma_write_uar_cq(struct pvrdma_dev *dev, u32 val)
+{
+ writel(cpu_to_le32(val), dev->driver_uar.map + PVRDMA_UAR_CQ_OFFSET);
+}
+
+static inline void pvrdma_write_uar_qp(struct pvrdma_dev *dev, u32 val)
+{
+ writel(cpu_to_le32(val), dev->driver_uar.map + PVRDMA_UAR_QP_OFFSET);
+}
+
+static inline void *pvrdma_page_dir_get_ptr(struct pvrdma_page_dir *pdir,
+ u64 offset)
+{
+ return pdir->pages[offset / PAGE_SIZE] + (offset % PAGE_SIZE);
+}
+
+static inline enum pvrdma_mtu ib_mtu_to_pvrdma(enum ib_mtu mtu)
+{
+ return (enum pvrdma_mtu)mtu;
+}
+
+static inline enum ib_mtu pvrdma_mtu_to_ib(enum pvrdma_mtu mtu)
+{
+ return (enum ib_mtu)mtu;
+}
+
+static inline enum pvrdma_port_state ib_port_state_to_pvrdma(
+ enum ib_port_state state)
+{
+ return (enum pvrdma_port_state)state;
+}
+
+static inline enum ib_port_state pvrdma_port_state_to_ib(
+ enum pvrdma_port_state state)
+{
+ return (enum ib_port_state)state;
+}
+
+static inline int ib_port_cap_flags_to_pvrdma(int flags)
+{
+ return flags & PVRDMA_MASK(PVRDMA_PORT_CAP_FLAGS_MAX);
+}
+
+static inline int pvrdma_port_cap_flags_to_ib(int flags)
+{
+ return flags;
+}
+
+static inline enum pvrdma_port_width ib_port_width_to_pvrdma(
+ enum ib_port_width width)
+{
+ return (enum pvrdma_port_width)width;
+}
+
+static inline enum ib_port_width pvrdma_port_width_to_ib(
+ enum pvrdma_port_width width)
+{
+ return (enum ib_port_width)width;
+}
+
+static inline enum pvrdma_port_speed ib_port_speed_to_pvrdma(
+ enum ib_port_speed speed)
+{
+ return (enum pvrdma_port_speed)speed;
+}
+
+static inline enum ib_port_speed pvrdma_port_speed_to_ib(
+ enum pvrdma_port_speed speed)
+{
+ return (enum ib_port_speed)speed;
+}
+
+static inline int pvrdma_qp_attr_mask_to_ib(int attr_mask)
+{
+ return attr_mask;
+}
+
+static inline int ib_qp_attr_mask_to_pvrdma(int attr_mask)
+{
+ return attr_mask & PVRDMA_MASK(PVRDMA_QP_ATTR_MASK_MAX);
+}
+
+static inline enum pvrdma_mig_state ib_mig_state_to_pvrdma(
+ enum ib_mig_state state)
+{
+ return (enum pvrdma_mig_state)state;
+}
+
+static inline enum ib_mig_state pvrdma_mig_state_to_ib(
+ enum pvrdma_mig_state state)
+{
+ return (enum ib_mig_state)state;
+}
+
+static inline int ib_access_flags_to_pvrdma(int flags)
+{
+ return flags;
+}
+
+static inline int pvrdma_access_flags_to_ib(int flags)
+{
+ return flags & PVRDMA_MASK(PVRDMA_ACCESS_FLAGS_MAX);
+}
+
+static inline enum pvrdma_qp_type ib_qp_type_to_pvrdma(enum ib_qp_type type)
+{
+ return (enum pvrdma_qp_type)type;
+}
+
+static inline enum ib_qp_type pvrdma_qp_type_to_ib(enum pvrdma_qp_type type)
+{
+ return (enum ib_qp_type)type;
+}
+
+static inline enum pvrdma_qp_state ib_qp_state_to_pvrdma(enum ib_qp_state state)
+{
+ return (enum pvrdma_qp_state)state;
+}
+
+static inline enum ib_qp_state pvrdma_qp_state_to_ib(enum pvrdma_qp_state state)
+{
+ return (enum ib_qp_state)state;
+}
+
+static inline enum pvrdma_wr_opcode ib_wr_opcode_to_pvrdma(enum ib_wr_opcode op)
+{
+ return (enum pvrdma_wr_opcode)op;
+}
+
+static inline enum ib_wc_status pvrdma_wc_status_to_ib(
+ enum pvrdma_wc_status status)
+{
+ return (enum ib_wc_status)status;
+}
+
+static inline int pvrdma_wc_opcode_to_ib(int opcode)
+{
+ return opcode;
+}
+
+static inline int pvrdma_wc_flags_to_ib(int flags)
+{
+ return flags;
+}
+
+static inline int ib_send_flags_to_pvrdma(int flags)
+{
+ return flags & PVRDMA_MASK(PVRDMA_SEND_FLAGS_MAX);
+}
+
+void pvrdma_qp_cap_to_ib(struct ib_qp_cap *dst,
+ const struct pvrdma_qp_cap *src);
+void ib_qp_cap_to_pvrdma(struct pvrdma_qp_cap *dst,
+ const struct ib_qp_cap *src);
+void pvrdma_gid_to_ib(union ib_gid *dst, const union pvrdma_gid *src);
+void ib_gid_to_pvrdma(union pvrdma_gid *dst, const union ib_gid *src);
+void pvrdma_global_route_to_ib(struct ib_global_route *dst,
+ const struct pvrdma_global_route *src);
+void ib_global_route_to_pvrdma(struct pvrdma_global_route *dst,
+ const struct ib_global_route *src);
+void pvrdma_ah_attr_to_ib(struct ib_ah_attr *dst,
+ const struct pvrdma_ah_attr *src);
+void ib_ah_attr_to_pvrdma(struct pvrdma_ah_attr *dst,
+ const struct ib_ah_attr *src);
+
+int pvrdma_uar_table_init(struct pvrdma_dev *dev);
+void pvrdma_uar_table_cleanup(struct pvrdma_dev *dev);
+
+int pvrdma_uar_alloc(struct pvrdma_dev *dev, struct pvrdma_uar_map *uar);
+void pvrdma_uar_free(struct pvrdma_dev *dev, struct pvrdma_uar_map *uar);
+
+void _pvrdma_flush_cqe(struct pvrdma_qp *qp, struct pvrdma_cq *cq);
+
+int pvrdma_page_dir_init(struct pvrdma_dev *dev, struct pvrdma_page_dir *pdir,
+ u64 npages, bool alloc_pages);
+void pvrdma_page_dir_cleanup(struct pvrdma_dev *dev,
+ struct pvrdma_page_dir *pdir);
+int pvrdma_page_dir_insert_dma(struct pvrdma_page_dir *pdir, u64 idx,
+ dma_addr_t daddr);
+int pvrdma_page_dir_insert_umem(struct pvrdma_page_dir *pdir,
+ struct ib_umem *umem, u64 offset);
+dma_addr_t pvrdma_page_dir_get_dma(struct pvrdma_page_dir *pdir, u64 idx);
+int pvrdma_page_dir_insert_page_list(struct pvrdma_page_dir *pdir,
+ u64 *page_list, int num_pages);
+
+int pvrdma_cmd_post(struct pvrdma_dev *dev, union pvrdma_cmd_req *req,
+ union pvrdma_cmd_resp *rsp, unsigned resp_code);
+
+#endif /* __PVRDMA_H__ */
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cmd.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cmd.c
new file mode 100644
index 000000000000..4a78c537d8a1
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cmd.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/list.h>
+
+#include "pvrdma.h"
+
+#define PVRDMA_CMD_TIMEOUT 10000 /* ms */
+
+static inline int pvrdma_cmd_recv(struct pvrdma_dev *dev,
+ union pvrdma_cmd_resp *resp,
+ unsigned resp_code)
+{
+ int err;
+
+ dev_dbg(&dev->pdev->dev, "receive response from device\n");
+
+ err = wait_for_completion_interruptible_timeout(&dev->cmd_done,
+ msecs_to_jiffies(PVRDMA_CMD_TIMEOUT));
+ if (err == 0 || err == -ERESTARTSYS) {
+ dev_warn(&dev->pdev->dev,
+ "completion timeout or interrupted\n");
+ return -ETIMEDOUT;
+ }
+
+ spin_lock(&dev->cmd_lock);
+ memcpy(resp, dev->resp_slot, sizeof(*resp));
+ spin_unlock(&dev->cmd_lock);
+
+ if (resp->hdr.ack != resp_code) {
+ dev_warn(&dev->pdev->dev,
+ "unknown response %#x expected %#x\n",
+ resp->hdr.ack, resp_code);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int
+pvrdma_cmd_post(struct pvrdma_dev *dev, union pvrdma_cmd_req *req,
+ union pvrdma_cmd_resp *resp, unsigned resp_code)
+{
+ int err;
+
+ dev_dbg(&dev->pdev->dev, "post request to device\n");
+
+ /* Serializiation */
+ down(&dev->cmd_sema);
+
+ BUILD_BUG_ON(sizeof(union pvrdma_cmd_req) !=
+ sizeof(struct pvrdma_cmd_modify_qp));
+
+ spin_lock(&dev->cmd_lock);
+ memcpy(dev->cmd_slot, req, sizeof(*req));
+ spin_unlock(&dev->cmd_lock);
+
+ init_completion(&dev->cmd_done);
+ pvrdma_write_reg(dev, PVRDMA_REG_REQUEST, 0);
+
+ /* Make sure the request is written before reading status. */
+ mb();
+
+ err = pvrdma_read_reg(dev, PVRDMA_REG_ERR);
+ if (err == 0) {
+ if (resp != NULL)
+ err = pvrdma_cmd_recv(dev, resp, resp_code);
+ } else {
+ dev_warn(&dev->pdev->dev,
+ "failed to write request error reg: %d\n", err);
+ err = -EFAULT;
+ }
+
+ up(&dev->cmd_sema);
+
+ return err;
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
new file mode 100644
index 000000000000..e429ca5b16aa
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "pvrdma.h"
+
+/**
+ * pvrdma_req_notify_cq - request notification for a completion queue
+ * @ibcq: the completion queue
+ * @notify_flags: notification flags
+ *
+ * @return: 0 for success.
+ */
+int pvrdma_req_notify_cq(struct ib_cq *ibcq,
+ enum ib_cq_notify_flags notify_flags)
+{
+ struct pvrdma_dev *dev = to_vdev(ibcq->device);
+ struct pvrdma_cq *cq = to_vcq(ibcq);
+ u32 val = cq->cq_handle;
+
+ val |= (notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
+ PVRDMA_UAR_CQ_ARM_SOL : PVRDMA_UAR_CQ_ARM;
+
+ pvrdma_write_uar_cq(dev, val);
+
+ return 0;
+}
+
+/**
+ * pvrdma_create_cq - create completion queue
+ * @ibdev: the device
+ * @attr: completion queue attributes
+ * @context: user context
+ * @udata: user data
+ *
+ * @return: ib_cq completion queue pointer on success,
+ * otherwise returns negative errno.
+ */
+struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *context,
+ struct ib_udata *udata)
+{
+ int entries = attr->cqe;
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+ struct pvrdma_cq *cq;
+ int ret;
+ int npages;
+ unsigned long flags;
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_cq *cmd = &req.create_cq;
+ struct pvrdma_cmd_create_cq_resp *resp = &rsp.create_cq_resp;
+ struct pvrdma_create_cq ucmd;
+
+ BUILD_BUG_ON(sizeof(struct pvrdma_cqe) != 64);
+
+ entries = roundup_pow_of_two(entries);
+ if (entries < 1 || entries > dev->dsr->caps.max_cqe)
+ return ERR_PTR(-EINVAL);
+
+ if (!atomic_add_unless(&dev->num_cqs, 1, dev->dsr->caps.max_cq))
+ return ERR_PTR(-ENOMEM);
+
+ cq = kzalloc(sizeof(*cq), GFP_KERNEL);
+ if (!cq) {
+ atomic_dec(&dev->num_cqs);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ cq->ibcq.cqe = entries;
+
+ if (context) {
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
+ ret = -EFAULT;
+ goto err_cq;
+ }
+
+ cq->umem = ib_umem_get(context, ucmd.buf_addr, ucmd.buf_size,
+ IB_ACCESS_LOCAL_WRITE, 1);
+ if (IS_ERR(cq->umem)) {
+ ret = PTR_ERR(cq->umem);
+ goto err_cq;
+ }
+
+ npages = ib_umem_page_count(cq->umem);
+ } else {
+ cq->is_kernel = true;
+
+ /* One extra page for shared ring state */
+ npages = 1 + (entries * sizeof(struct pvrdma_cqe) +
+ PAGE_SIZE - 1) / PAGE_SIZE;
+
+ /* Skip header page. */
+ cq->offset = PAGE_SIZE;
+ }
+
+ if (npages < 0 || npages > PVRDMA_PAGE_DIR_MAX_PAGES) {
+ dev_warn(&dev->pdev->dev,
+ "overflow pages in completion queue\n");
+ ret = -EINVAL;
+ goto err_umem;
+ }
+
+ ret = pvrdma_page_dir_init(dev, &cq->pdir, npages, cq->is_kernel);
+ if (ret) {
+ dev_warn(&dev->pdev->dev,
+ "could not allocate page directory\n");
+ goto err_umem;
+ }
+
+ /* Ring state is always the first page. Set in library for user cq. */
+ if (cq->is_kernel)
+ cq->ring_state = cq->pdir.pages[0];
+ else
+ pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0);
+
+ atomic_set(&cq->refcnt, 1);
+ init_waitqueue_head(&cq->wait);
+ spin_lock_init(&cq->cq_lock);
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_CQ;
+ cmd->nchunks = npages;
+ cmd->ctx_handle = (context) ?
+ (u64)to_vucontext(context)->ctx_handle : 0;
+ cmd->cqe = entries;
+ cmd->pdir_dma = cq->pdir.dir_dma;
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_CQ_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not create completion queue, error: %d\n", ret);
+ goto err_page_dir;
+ }
+
+ cq->ibcq.cqe = resp->cqe;
+ cq->cq_handle = resp->cq_handle;
+ spin_lock_irqsave(&dev->cq_tbl_lock, flags);
+ dev->cq_tbl[cq->cq_handle % dev->dsr->caps.max_cq] = cq;
+ spin_unlock_irqrestore(&dev->cq_tbl_lock, flags);
+
+ if (context) {
+ cq->uar = &(to_vucontext(context)->uar);
+
+ /* Copy udata back. */
+ if (ib_copy_to_udata(udata, &cq->cq_handle, sizeof(__u32))) {
+ dev_warn(&dev->pdev->dev,
+ "failed to copy back udata\n");
+ pvrdma_destroy_cq(&cq->ibcq);
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ return &cq->ibcq;
+
+err_page_dir:
+ pvrdma_page_dir_cleanup(dev, &cq->pdir);
+err_umem:
+ if (context)
+ ib_umem_release(cq->umem);
+err_cq:
+ atomic_dec(&dev->num_cqs);
+ kfree(cq);
+
+ return ERR_PTR(ret);
+}
+
+static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq)
+{
+ atomic_dec(&cq->refcnt);
+ wait_event(cq->wait, !atomic_read(&cq->refcnt));
+
+ if (!cq->is_kernel)
+ ib_umem_release(cq->umem);
+
+ pvrdma_page_dir_cleanup(dev, &cq->pdir);
+ kfree(cq);
+}
+
+/**
+ * pvrdma_destroy_cq - destroy completion queue
+ * @cq: the completion queue to destroy.
+ *
+ * @return: 0 for success.
+ */
+int pvrdma_destroy_cq(struct ib_cq *cq)
+{
+ struct pvrdma_cq *vcq = to_vcq(cq);
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_destroy_cq *cmd = &req.destroy_cq;
+ struct pvrdma_dev *dev = to_vdev(cq->device);
+ unsigned long flags;
+ int ret;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_DESTROY_CQ;
+ cmd->cq_handle = vcq->cq_handle;
+
+ ret = pvrdma_cmd_post(dev, &req, NULL, 0);
+ if (ret < 0)
+ dev_warn(&dev->pdev->dev,
+ "could not destroy completion queue, error: %d\n",
+ ret);
+
+ /* free cq's resources */
+ spin_lock_irqsave(&dev->cq_tbl_lock, flags);
+ dev->cq_tbl[vcq->cq_handle] = NULL;
+ spin_unlock_irqrestore(&dev->cq_tbl_lock, flags);
+
+ pvrdma_free_cq(dev, vcq);
+ atomic_dec(&dev->num_cqs);
+
+ return ret;
+}
+
+/**
+ * pvrdma_modify_cq - modify the CQ moderation parameters
+ * @ibcq: the CQ to modify
+ * @cq_count: number of CQEs that will trigger an event
+ * @cq_period: max period of time in usec before triggering an event
+ *
+ * @return: -EOPNOTSUPP as CQ resize is not supported.
+ */
+int pvrdma_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline struct pvrdma_cqe *get_cqe(struct pvrdma_cq *cq, int i)
+{
+ return (struct pvrdma_cqe *)pvrdma_page_dir_get_ptr(
+ &cq->pdir,
+ cq->offset +
+ sizeof(struct pvrdma_cqe) * i);
+}
+
+void _pvrdma_flush_cqe(struct pvrdma_qp *qp, struct pvrdma_cq *cq)
+{
+ int head;
+ int has_data;
+
+ if (!cq->is_kernel)
+ return;
+
+ /* Lock held */
+ has_data = pvrdma_idx_ring_has_data(&cq->ring_state->rx,
+ cq->ibcq.cqe, &head);
+ if (unlikely(has_data > 0)) {
+ int items;
+ int curr;
+ int tail = pvrdma_idx(&cq->ring_state->rx.prod_tail,
+ cq->ibcq.cqe);
+ struct pvrdma_cqe *cqe;
+ struct pvrdma_cqe *curr_cqe;
+
+ items = (tail > head) ? (tail - head) :
+ (cq->ibcq.cqe - head + tail);
+ curr = --tail;
+ while (items-- > 0) {
+ if (curr < 0)
+ curr = cq->ibcq.cqe - 1;
+ if (tail < 0)
+ tail = cq->ibcq.cqe - 1;
+ curr_cqe = get_cqe(cq, curr);
+ if ((curr_cqe->qp & 0xFFFF) != qp->qp_handle) {
+ if (curr != tail) {
+ cqe = get_cqe(cq, tail);
+ *cqe = *curr_cqe;
+ }
+ tail--;
+ } else {
+ pvrdma_idx_ring_inc(
+ &cq->ring_state->rx.cons_head,
+ cq->ibcq.cqe);
+ }
+ curr--;
+ }
+ }
+}
+
+static int pvrdma_poll_one(struct pvrdma_cq *cq, struct pvrdma_qp **cur_qp,
+ struct ib_wc *wc)
+{
+ struct pvrdma_dev *dev = to_vdev(cq->ibcq.device);
+ int has_data;
+ unsigned int head;
+ bool tried = false;
+ struct pvrdma_cqe *cqe;
+
+retry:
+ has_data = pvrdma_idx_ring_has_data(&cq->ring_state->rx,
+ cq->ibcq.cqe, &head);
+ if (has_data == 0) {
+ if (tried)
+ return -EAGAIN;
+
+ pvrdma_write_uar_cq(dev, cq->cq_handle | PVRDMA_UAR_CQ_POLL);
+
+ tried = true;
+ goto retry;
+ } else if (has_data == PVRDMA_INVALID_IDX) {
+ dev_err(&dev->pdev->dev, "CQ ring state invalid\n");
+ return -EAGAIN;
+ }
+
+ cqe = get_cqe(cq, head);
+
+ /* Ensure cqe is valid. */
+ rmb();
+ if (dev->qp_tbl[cqe->qp & 0xffff])
+ *cur_qp = (struct pvrdma_qp *)dev->qp_tbl[cqe->qp & 0xffff];
+ else
+ return -EAGAIN;
+
+ wc->opcode = pvrdma_wc_opcode_to_ib(cqe->opcode);
+ wc->status = pvrdma_wc_status_to_ib(cqe->status);
+ wc->wr_id = cqe->wr_id;
+ wc->qp = &(*cur_qp)->ibqp;
+ wc->byte_len = cqe->byte_len;
+ wc->ex.imm_data = cqe->imm_data;
+ wc->src_qp = cqe->src_qp;
+ wc->wc_flags = pvrdma_wc_flags_to_ib(cqe->wc_flags);
+ wc->pkey_index = cqe->pkey_index;
+ wc->slid = cqe->slid;
+ wc->sl = cqe->sl;
+ wc->dlid_path_bits = cqe->dlid_path_bits;
+ wc->port_num = cqe->port_num;
+ wc->vendor_err = 0;
+
+ /* Update shared ring state */
+ pvrdma_idx_ring_inc(&cq->ring_state->rx.cons_head, cq->ibcq.cqe);
+
+ return 0;
+}
+
+/**
+ * pvrdma_poll_cq - poll for work completion queue entries
+ * @ibcq: completion queue
+ * @num_entries: the maximum number of entries
+ * @entry: pointer to work completion array
+ *
+ * @return: number of polled completion entries
+ */
+int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
+{
+ struct pvrdma_cq *cq = to_vcq(ibcq);
+ struct pvrdma_qp *cur_qp = NULL;
+ unsigned long flags;
+ int npolled;
+
+ if (num_entries < 1 || wc == NULL)
+ return 0;
+
+ spin_lock_irqsave(&cq->cq_lock, flags);
+ for (npolled = 0; npolled < num_entries; ++npolled) {
+ if (pvrdma_poll_one(cq, &cur_qp, wc + npolled))
+ break;
+ }
+
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
+
+ /* Ensure we do not return errors from poll_cq */
+ return npolled;
+}
+
+/**
+ * pvrdma_resize_cq - resize CQ
+ * @ibcq: the completion queue
+ * @entries: CQ entries
+ * @udata: user data
+ *
+ * @return: -EOPNOTSUPP as CQ resize is not supported.
+ */
+int pvrdma_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+{
+ return -EOPNOTSUPP;
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
new file mode 100644
index 000000000000..c06768635d65
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PVRDMA_DEV_API_H__
+#define __PVRDMA_DEV_API_H__
+
+#include <linux/types.h>
+
+#include "pvrdma_verbs.h"
+
+#define PVRDMA_VERSION 17
+#define PVRDMA_BOARD_ID 1
+#define PVRDMA_REV_ID 1
+
+/*
+ * Masks and accessors for page directory, which is a two-level lookup:
+ * page directory -> page table -> page. Only one directory for now, but we
+ * could expand that easily. 9 bits for tables, 9 bits for pages, gives one
+ * gigabyte for memory regions and so forth.
+ */
+
+#define PVRDMA_PDIR_SHIFT 18
+#define PVRDMA_PTABLE_SHIFT 9
+#define PVRDMA_PAGE_DIR_DIR(x) (((x) >> PVRDMA_PDIR_SHIFT) & 0x1)
+#define PVRDMA_PAGE_DIR_TABLE(x) (((x) >> PVRDMA_PTABLE_SHIFT) & 0x1ff)
+#define PVRDMA_PAGE_DIR_PAGE(x) ((x) & 0x1ff)
+#define PVRDMA_PAGE_DIR_MAX_PAGES (1 * 512 * 512)
+#define PVRDMA_MAX_FAST_REG_PAGES 128
+
+/*
+ * Max MSI-X vectors.
+ */
+
+#define PVRDMA_MAX_INTERRUPTS 3
+
+/* Register offsets within PCI resource on BAR1. */
+#define PVRDMA_REG_VERSION 0x00 /* R: Version of device. */
+#define PVRDMA_REG_DSRLOW 0x04 /* W: Device shared region low PA. */
+#define PVRDMA_REG_DSRHIGH 0x08 /* W: Device shared region high PA. */
+#define PVRDMA_REG_CTL 0x0c /* W: PVRDMA_DEVICE_CTL */
+#define PVRDMA_REG_REQUEST 0x10 /* W: Indicate device request. */
+#define PVRDMA_REG_ERR 0x14 /* R: Device error. */
+#define PVRDMA_REG_ICR 0x18 /* R: Interrupt cause. */
+#define PVRDMA_REG_IMR 0x1c /* R/W: Interrupt mask. */
+#define PVRDMA_REG_MACL 0x20 /* R/W: MAC address low. */
+#define PVRDMA_REG_MACH 0x24 /* R/W: MAC address high. */
+
+/* Object flags. */
+#define PVRDMA_CQ_FLAG_ARMED_SOL BIT(0) /* Armed for solicited-only. */
+#define PVRDMA_CQ_FLAG_ARMED BIT(1) /* Armed. */
+#define PVRDMA_MR_FLAG_DMA BIT(0) /* DMA region. */
+#define PVRDMA_MR_FLAG_FRMR BIT(1) /* Fast reg memory region. */
+
+/*
+ * Atomic operation capability (masked versions are extended atomic
+ * operations.
+ */
+
+#define PVRDMA_ATOMIC_OP_COMP_SWAP BIT(0) /* Compare and swap. */
+#define PVRDMA_ATOMIC_OP_FETCH_ADD BIT(1) /* Fetch and add. */
+#define PVRDMA_ATOMIC_OP_MASK_COMP_SWAP BIT(2) /* Masked compare and swap. */
+#define PVRDMA_ATOMIC_OP_MASK_FETCH_ADD BIT(3) /* Masked fetch and add. */
+
+/*
+ * Base Memory Management Extension flags to support Fast Reg Memory Regions
+ * and Fast Reg Work Requests. Each flag represents a verb operation and we
+ * must support all of them to qualify for the BMME device cap.
+ */
+
+#define PVRDMA_BMME_FLAG_LOCAL_INV BIT(0) /* Local Invalidate. */
+#define PVRDMA_BMME_FLAG_REMOTE_INV BIT(1) /* Remote Invalidate. */
+#define PVRDMA_BMME_FLAG_FAST_REG_WR BIT(2) /* Fast Reg Work Request. */
+
+/*
+ * GID types. The interpretation of the gid_types bit field in the device
+ * capabilities will depend on the device mode. For now, the device only
+ * supports RoCE as mode, so only the different GID types for RoCE are
+ * defined.
+ */
+
+#define PVRDMA_GID_TYPE_FLAG_ROCE_V1 BIT(0)
+#define PVRDMA_GID_TYPE_FLAG_ROCE_V2 BIT(1)
+
+enum pvrdma_pci_resource {
+ PVRDMA_PCI_RESOURCE_MSIX, /* BAR0: MSI-X, MMIO. */
+ PVRDMA_PCI_RESOURCE_REG, /* BAR1: Registers, MMIO. */
+ PVRDMA_PCI_RESOURCE_UAR, /* BAR2: UAR pages, MMIO, 64-bit. */
+ PVRDMA_PCI_RESOURCE_LAST, /* Last. */
+};
+
+enum pvrdma_device_ctl {
+ PVRDMA_DEVICE_CTL_ACTIVATE, /* Activate device. */
+ PVRDMA_DEVICE_CTL_QUIESCE, /* Quiesce device. */
+ PVRDMA_DEVICE_CTL_RESET, /* Reset device. */
+};
+
+enum pvrdma_intr_vector {
+ PVRDMA_INTR_VECTOR_RESPONSE, /* Command response. */
+ PVRDMA_INTR_VECTOR_ASYNC, /* Async events. */
+ PVRDMA_INTR_VECTOR_CQ, /* CQ notification. */
+ /* Additional CQ notification vectors. */
+};
+
+enum pvrdma_intr_cause {
+ PVRDMA_INTR_CAUSE_RESPONSE = (1 << PVRDMA_INTR_VECTOR_RESPONSE),
+ PVRDMA_INTR_CAUSE_ASYNC = (1 << PVRDMA_INTR_VECTOR_ASYNC),
+ PVRDMA_INTR_CAUSE_CQ = (1 << PVRDMA_INTR_VECTOR_CQ),
+};
+
+enum pvrdma_intr_type {
+ PVRDMA_INTR_TYPE_INTX, /* Legacy. */
+ PVRDMA_INTR_TYPE_MSI, /* MSI. */
+ PVRDMA_INTR_TYPE_MSIX, /* MSI-X. */
+};
+
+enum pvrdma_gos_bits {
+ PVRDMA_GOS_BITS_UNK, /* Unknown. */
+ PVRDMA_GOS_BITS_32, /* 32-bit. */
+ PVRDMA_GOS_BITS_64, /* 64-bit. */
+};
+
+enum pvrdma_gos_type {
+ PVRDMA_GOS_TYPE_UNK, /* Unknown. */
+ PVRDMA_GOS_TYPE_LINUX, /* Linux. */
+};
+
+enum pvrdma_device_mode {
+ PVRDMA_DEVICE_MODE_ROCE, /* RoCE. */
+ PVRDMA_DEVICE_MODE_IWARP, /* iWarp. */
+ PVRDMA_DEVICE_MODE_IB, /* InfiniBand. */
+};
+
+struct pvrdma_gos_info {
+ u32 gos_bits:2; /* W: PVRDMA_GOS_BITS_ */
+ u32 gos_type:4; /* W: PVRDMA_GOS_TYPE_ */
+ u32 gos_ver:16; /* W: Guest OS version. */
+ u32 gos_misc:10; /* W: Other. */
+ u32 pad; /* Pad to 8-byte alignment. */
+};
+
+struct pvrdma_device_caps {
+ u64 fw_ver; /* R: Query device. */
+ __be64 node_guid;
+ __be64 sys_image_guid;
+ u64 max_mr_size;
+ u64 page_size_cap;
+ u64 atomic_arg_sizes; /* EX verbs. */
+ u32 ex_comp_mask; /* EX verbs. */
+ u32 device_cap_flags2; /* EX verbs. */
+ u32 max_fa_bit_boundary; /* EX verbs. */
+ u32 log_max_atomic_inline_arg; /* EX verbs. */
+ u32 vendor_id;
+ u32 vendor_part_id;
+ u32 hw_ver;
+ u32 max_qp;
+ u32 max_qp_wr;
+ u32 device_cap_flags;
+ u32 max_sge;
+ u32 max_sge_rd;
+ u32 max_cq;
+ u32 max_cqe;
+ u32 max_mr;
+ u32 max_pd;
+ u32 max_qp_rd_atom;
+ u32 max_ee_rd_atom;
+ u32 max_res_rd_atom;
+ u32 max_qp_init_rd_atom;
+ u32 max_ee_init_rd_atom;
+ u32 max_ee;
+ u32 max_rdd;
+ u32 max_mw;
+ u32 max_raw_ipv6_qp;
+ u32 max_raw_ethy_qp;
+ u32 max_mcast_grp;
+ u32 max_mcast_qp_attach;
+ u32 max_total_mcast_qp_attach;
+ u32 max_ah;
+ u32 max_fmr;
+ u32 max_map_per_fmr;
+ u32 max_srq;
+ u32 max_srq_wr;
+ u32 max_srq_sge;
+ u32 max_uar;
+ u32 gid_tbl_len;
+ u16 max_pkeys;
+ u8 local_ca_ack_delay;
+ u8 phys_port_cnt;
+ u8 mode; /* PVRDMA_DEVICE_MODE_ */
+ u8 atomic_ops; /* PVRDMA_ATOMIC_OP_* bits */
+ u8 bmme_flags; /* FRWR Mem Mgmt Extensions */
+ u8 gid_types; /* PVRDMA_GID_TYPE_FLAG_ */
+ u8 reserved[4];
+};
+
+struct pvrdma_ring_page_info {
+ u32 num_pages; /* Num pages incl. header. */
+ u32 reserved; /* Reserved. */
+ u64 pdir_dma; /* Page directory PA. */
+};
+
+#pragma pack(push, 1)
+
+struct pvrdma_device_shared_region {
+ u32 driver_version; /* W: Driver version. */
+ u32 pad; /* Pad to 8-byte align. */
+ struct pvrdma_gos_info gos_info; /* W: Guest OS information. */
+ u64 cmd_slot_dma; /* W: Command slot address. */
+ u64 resp_slot_dma; /* W: Response slot address. */
+ struct pvrdma_ring_page_info async_ring_pages;
+ /* W: Async ring page info. */
+ struct pvrdma_ring_page_info cq_ring_pages;
+ /* W: CQ ring page info. */
+ u32 uar_pfn; /* W: UAR pageframe. */
+ u32 pad2; /* Pad to 8-byte align. */
+ struct pvrdma_device_caps caps; /* R: Device capabilities. */
+};
+
+#pragma pack(pop)
+
+/* Event types. Currently a 1:1 mapping with enum ib_event. */
+enum pvrdma_eqe_type {
+ PVRDMA_EVENT_CQ_ERR,
+ PVRDMA_EVENT_QP_FATAL,
+ PVRDMA_EVENT_QP_REQ_ERR,
+ PVRDMA_EVENT_QP_ACCESS_ERR,
+ PVRDMA_EVENT_COMM_EST,
+ PVRDMA_EVENT_SQ_DRAINED,
+ PVRDMA_EVENT_PATH_MIG,
+ PVRDMA_EVENT_PATH_MIG_ERR,
+ PVRDMA_EVENT_DEVICE_FATAL,
+ PVRDMA_EVENT_PORT_ACTIVE,
+ PVRDMA_EVENT_PORT_ERR,
+ PVRDMA_EVENT_LID_CHANGE,
+ PVRDMA_EVENT_PKEY_CHANGE,
+ PVRDMA_EVENT_SM_CHANGE,
+ PVRDMA_EVENT_SRQ_ERR,
+ PVRDMA_EVENT_SRQ_LIMIT_REACHED,
+ PVRDMA_EVENT_QP_LAST_WQE_REACHED,
+ PVRDMA_EVENT_CLIENT_REREGISTER,
+ PVRDMA_EVENT_GID_CHANGE,
+};
+
+/* Event queue element. */
+struct pvrdma_eqe {
+ u32 type; /* Event type. */
+ u32 info; /* Handle, other. */
+};
+
+/* CQ notification queue element. */
+struct pvrdma_cqne {
+ u32 info; /* Handle */
+};
+
+enum {
+ PVRDMA_CMD_FIRST,
+ PVRDMA_CMD_QUERY_PORT = PVRDMA_CMD_FIRST,
+ PVRDMA_CMD_QUERY_PKEY,
+ PVRDMA_CMD_CREATE_PD,
+ PVRDMA_CMD_DESTROY_PD,
+ PVRDMA_CMD_CREATE_MR,
+ PVRDMA_CMD_DESTROY_MR,
+ PVRDMA_CMD_CREATE_CQ,
+ PVRDMA_CMD_RESIZE_CQ,
+ PVRDMA_CMD_DESTROY_CQ,
+ PVRDMA_CMD_CREATE_QP,
+ PVRDMA_CMD_MODIFY_QP,
+ PVRDMA_CMD_QUERY_QP,
+ PVRDMA_CMD_DESTROY_QP,
+ PVRDMA_CMD_CREATE_UC,
+ PVRDMA_CMD_DESTROY_UC,
+ PVRDMA_CMD_CREATE_BIND,
+ PVRDMA_CMD_DESTROY_BIND,
+ PVRDMA_CMD_MAX,
+};
+
+enum {
+ PVRDMA_CMD_FIRST_RESP = (1 << 31),
+ PVRDMA_CMD_QUERY_PORT_RESP = PVRDMA_CMD_FIRST_RESP,
+ PVRDMA_CMD_QUERY_PKEY_RESP,
+ PVRDMA_CMD_CREATE_PD_RESP,
+ PVRDMA_CMD_DESTROY_PD_RESP_NOOP,
+ PVRDMA_CMD_CREATE_MR_RESP,
+ PVRDMA_CMD_DESTROY_MR_RESP_NOOP,
+ PVRDMA_CMD_CREATE_CQ_RESP,
+ PVRDMA_CMD_RESIZE_CQ_RESP,
+ PVRDMA_CMD_DESTROY_CQ_RESP_NOOP,
+ PVRDMA_CMD_CREATE_QP_RESP,
+ PVRDMA_CMD_MODIFY_QP_RESP,
+ PVRDMA_CMD_QUERY_QP_RESP,
+ PVRDMA_CMD_DESTROY_QP_RESP,
+ PVRDMA_CMD_CREATE_UC_RESP,
+ PVRDMA_CMD_DESTROY_UC_RESP_NOOP,
+ PVRDMA_CMD_CREATE_BIND_RESP_NOOP,
+ PVRDMA_CMD_DESTROY_BIND_RESP_NOOP,
+ PVRDMA_CMD_MAX_RESP,
+};
+
+struct pvrdma_cmd_hdr {
+ u64 response; /* Key for response lookup. */
+ u32 cmd; /* PVRDMA_CMD_ */
+ u32 reserved; /* Reserved. */
+};
+
+struct pvrdma_cmd_resp_hdr {
+ u64 response; /* From cmd hdr. */
+ u32 ack; /* PVRDMA_CMD_XXX_RESP */
+ u8 err; /* Error. */
+ u8 reserved[3]; /* Reserved. */
+};
+
+struct pvrdma_cmd_query_port {
+ struct pvrdma_cmd_hdr hdr;
+ u8 port_num;
+ u8 reserved[7];
+};
+
+struct pvrdma_cmd_query_port_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ struct pvrdma_port_attr attrs;
+};
+
+struct pvrdma_cmd_query_pkey {
+ struct pvrdma_cmd_hdr hdr;
+ u8 port_num;
+ u8 index;
+ u8 reserved[6];
+};
+
+struct pvrdma_cmd_query_pkey_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u16 pkey;
+ u8 reserved[6];
+};
+
+struct pvrdma_cmd_create_uc {
+ struct pvrdma_cmd_hdr hdr;
+ u32 pfn; /* UAR page frame number */
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_uc_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 ctx_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_destroy_uc {
+ struct pvrdma_cmd_hdr hdr;
+ u32 ctx_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_pd {
+ struct pvrdma_cmd_hdr hdr;
+ u32 ctx_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_pd_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 pd_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_destroy_pd {
+ struct pvrdma_cmd_hdr hdr;
+ u32 pd_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_mr {
+ struct pvrdma_cmd_hdr hdr;
+ u64 start;
+ u64 length;
+ u64 pdir_dma;
+ u32 pd_handle;
+ u32 access_flags;
+ u32 flags;
+ u32 nchunks;
+};
+
+struct pvrdma_cmd_create_mr_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 mr_handle;
+ u32 lkey;
+ u32 rkey;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_destroy_mr {
+ struct pvrdma_cmd_hdr hdr;
+ u32 mr_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_cq {
+ struct pvrdma_cmd_hdr hdr;
+ u64 pdir_dma;
+ u32 ctx_handle;
+ u32 cqe;
+ u32 nchunks;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_cq_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 cq_handle;
+ u32 cqe;
+};
+
+struct pvrdma_cmd_resize_cq {
+ struct pvrdma_cmd_hdr hdr;
+ u32 cq_handle;
+ u32 cqe;
+};
+
+struct pvrdma_cmd_resize_cq_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 cqe;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_destroy_cq {
+ struct pvrdma_cmd_hdr hdr;
+ u32 cq_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_qp {
+ struct pvrdma_cmd_hdr hdr;
+ u64 pdir_dma;
+ u32 pd_handle;
+ u32 send_cq_handle;
+ u32 recv_cq_handle;
+ u32 srq_handle;
+ u32 max_send_wr;
+ u32 max_recv_wr;
+ u32 max_send_sge;
+ u32 max_recv_sge;
+ u32 max_inline_data;
+ u32 lkey;
+ u32 access_flags;
+ u16 total_chunks;
+ u16 send_chunks;
+ u16 max_atomic_arg;
+ u8 sq_sig_all;
+ u8 qp_type;
+ u8 is_srq;
+ u8 reserved[3];
+};
+
+struct pvrdma_cmd_create_qp_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 qpn;
+ u32 max_send_wr;
+ u32 max_recv_wr;
+ u32 max_send_sge;
+ u32 max_recv_sge;
+ u32 max_inline_data;
+};
+
+struct pvrdma_cmd_modify_qp {
+ struct pvrdma_cmd_hdr hdr;
+ u32 qp_handle;
+ u32 attr_mask;
+ struct pvrdma_qp_attr attrs;
+};
+
+struct pvrdma_cmd_query_qp {
+ struct pvrdma_cmd_hdr hdr;
+ u32 qp_handle;
+ u32 attr_mask;
+};
+
+struct pvrdma_cmd_query_qp_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ struct pvrdma_qp_attr attrs;
+};
+
+struct pvrdma_cmd_destroy_qp {
+ struct pvrdma_cmd_hdr hdr;
+ u32 qp_handle;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_destroy_qp_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ u32 events_reported;
+ u8 reserved[4];
+};
+
+struct pvrdma_cmd_create_bind {
+ struct pvrdma_cmd_hdr hdr;
+ u32 mtu;
+ u32 vlan;
+ u32 index;
+ u8 new_gid[16];
+ u8 gid_type;
+ u8 reserved[3];
+};
+
+struct pvrdma_cmd_destroy_bind {
+ struct pvrdma_cmd_hdr hdr;
+ u32 index;
+ u8 dest_gid[16];
+ u8 reserved[4];
+};
+
+union pvrdma_cmd_req {
+ struct pvrdma_cmd_hdr hdr;
+ struct pvrdma_cmd_query_port query_port;
+ struct pvrdma_cmd_query_pkey query_pkey;
+ struct pvrdma_cmd_create_uc create_uc;
+ struct pvrdma_cmd_destroy_uc destroy_uc;
+ struct pvrdma_cmd_create_pd create_pd;
+ struct pvrdma_cmd_destroy_pd destroy_pd;
+ struct pvrdma_cmd_create_mr create_mr;
+ struct pvrdma_cmd_destroy_mr destroy_mr;
+ struct pvrdma_cmd_create_cq create_cq;
+ struct pvrdma_cmd_resize_cq resize_cq;
+ struct pvrdma_cmd_destroy_cq destroy_cq;
+ struct pvrdma_cmd_create_qp create_qp;
+ struct pvrdma_cmd_modify_qp modify_qp;
+ struct pvrdma_cmd_query_qp query_qp;
+ struct pvrdma_cmd_destroy_qp destroy_qp;
+ struct pvrdma_cmd_create_bind create_bind;
+ struct pvrdma_cmd_destroy_bind destroy_bind;
+};
+
+union pvrdma_cmd_resp {
+ struct pvrdma_cmd_resp_hdr hdr;
+ struct pvrdma_cmd_query_port_resp query_port_resp;
+ struct pvrdma_cmd_query_pkey_resp query_pkey_resp;
+ struct pvrdma_cmd_create_uc_resp create_uc_resp;
+ struct pvrdma_cmd_create_pd_resp create_pd_resp;
+ struct pvrdma_cmd_create_mr_resp create_mr_resp;
+ struct pvrdma_cmd_create_cq_resp create_cq_resp;
+ struct pvrdma_cmd_resize_cq_resp resize_cq_resp;
+ struct pvrdma_cmd_create_qp_resp create_qp_resp;
+ struct pvrdma_cmd_query_qp_resp query_qp_resp;
+ struct pvrdma_cmd_destroy_qp_resp destroy_qp_resp;
+};
+
+#endif /* __PVRDMA_DEV_API_H__ */
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_doorbell.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_doorbell.c
new file mode 100644
index 000000000000..bf51357ea3aa
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_doorbell.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/bitmap.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include "pvrdma.h"
+
+int pvrdma_uar_table_init(struct pvrdma_dev *dev)
+{
+ u32 num = dev->dsr->caps.max_uar;
+ u32 mask = num - 1;
+ struct pvrdma_id_table *tbl = &dev->uar_table.tbl;
+
+ if (!is_power_of_2(num))
+ return -EINVAL;
+
+ tbl->last = 0;
+ tbl->top = 0;
+ tbl->max = num;
+ tbl->mask = mask;
+ spin_lock_init(&tbl->lock);
+ tbl->table = kcalloc(BITS_TO_LONGS(num), sizeof(long), GFP_KERNEL);
+ if (!tbl->table)
+ return -ENOMEM;
+
+ /* 0th UAR is taken by the device. */
+ set_bit(0, tbl->table);
+
+ return 0;
+}
+
+void pvrdma_uar_table_cleanup(struct pvrdma_dev *dev)
+{
+ struct pvrdma_id_table *tbl = &dev->uar_table.tbl;
+
+ kfree(tbl->table);
+}
+
+int pvrdma_uar_alloc(struct pvrdma_dev *dev, struct pvrdma_uar_map *uar)
+{
+ struct pvrdma_id_table *tbl;
+ unsigned long flags;
+ u32 obj;
+
+ tbl = &dev->uar_table.tbl;
+
+ spin_lock_irqsave(&tbl->lock, flags);
+ obj = find_next_zero_bit(tbl->table, tbl->max, tbl->last);
+ if (obj >= tbl->max) {
+ tbl->top = (tbl->top + tbl->max) & tbl->mask;
+ obj = find_first_zero_bit(tbl->table, tbl->max);
+ }
+
+ if (obj >= tbl->max) {
+ spin_unlock_irqrestore(&tbl->lock, flags);
+ return -ENOMEM;
+ }
+
+ set_bit(obj, tbl->table);
+ obj |= tbl->top;
+
+ spin_unlock_irqrestore(&tbl->lock, flags);
+
+ uar->index = obj;
+ uar->pfn = (pci_resource_start(dev->pdev, PVRDMA_PCI_RESOURCE_UAR) >>
+ PAGE_SHIFT) + uar->index;
+
+ return 0;
+}
+
+void pvrdma_uar_free(struct pvrdma_dev *dev, struct pvrdma_uar_map *uar)
+{
+ struct pvrdma_id_table *tbl = &dev->uar_table.tbl;
+ unsigned long flags;
+ u32 obj;
+
+ obj = uar->index & (tbl->max - 1);
+ spin_lock_irqsave(&tbl->lock, flags);
+ clear_bit(obj, tbl->table);
+ tbl->last = min(tbl->last, obj);
+ tbl->top = (tbl->top + tbl->max) & tbl->mask;
+ spin_unlock_irqrestore(&tbl->lock, flags);
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
new file mode 100644
index 000000000000..231a1ce1f4be
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
@@ -0,0 +1,1211 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/errno.h>
+#include <linux/inetdevice.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <net/addrconf.h>
+
+#include "pvrdma.h"
+
+#define DRV_NAME "vmw_pvrdma"
+#define DRV_VERSION "1.0.0.0-k"
+
+static DEFINE_MUTEX(pvrdma_device_list_lock);
+static LIST_HEAD(pvrdma_device_list);
+static struct workqueue_struct *event_wq;
+
+static int pvrdma_add_gid(struct ib_device *ibdev,
+ u8 port_num,
+ unsigned int index,
+ const union ib_gid *gid,
+ const struct ib_gid_attr *attr,
+ void **context);
+static int pvrdma_del_gid(struct ib_device *ibdev,
+ u8 port_num,
+ unsigned int index,
+ void **context);
+
+
+static ssize_t show_hca(struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "VMW_PVRDMA-%s\n", DRV_VERSION);
+}
+
+static ssize_t show_rev(struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", PVRDMA_REV_ID);
+}
+
+static ssize_t show_board(struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", PVRDMA_BOARD_ID);
+}
+
+static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
+static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
+static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
+
+static struct device_attribute *pvrdma_class_attributes[] = {
+ &dev_attr_hw_rev,
+ &dev_attr_hca_type,
+ &dev_attr_board_id
+};
+
+static void pvrdma_get_fw_ver_str(struct ib_device *device, char *str,
+ size_t str_len)
+{
+ struct pvrdma_dev *dev =
+ container_of(device, struct pvrdma_dev, ib_dev);
+ snprintf(str, str_len, "%d.%d.%d\n",
+ (int) (dev->dsr->caps.fw_ver >> 32),
+ (int) (dev->dsr->caps.fw_ver >> 16) & 0xffff,
+ (int) dev->dsr->caps.fw_ver & 0xffff);
+}
+
+static int pvrdma_init_device(struct pvrdma_dev *dev)
+{
+ /* Initialize some device related stuff */
+ spin_lock_init(&dev->cmd_lock);
+ sema_init(&dev->cmd_sema, 1);
+ atomic_set(&dev->num_qps, 0);
+ atomic_set(&dev->num_cqs, 0);
+ atomic_set(&dev->num_pds, 0);
+ atomic_set(&dev->num_ahs, 0);
+
+ return 0;
+}
+
+static int pvrdma_port_immutable(struct ib_device *ibdev, u8 port_num,
+ struct ib_port_immutable *immutable)
+{
+ struct ib_port_attr attr;
+ int err;
+
+ err = pvrdma_query_port(ibdev, port_num, &attr);
+ if (err)
+ return err;
+
+ immutable->pkey_tbl_len = attr.pkey_tbl_len;
+ immutable->gid_tbl_len = attr.gid_tbl_len;
+ immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE;
+ immutable->max_mad_size = IB_MGMT_MAD_SIZE;
+ return 0;
+}
+
+static struct net_device *pvrdma_get_netdev(struct ib_device *ibdev,
+ u8 port_num)
+{
+ struct net_device *netdev;
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+
+ if (port_num != 1)
+ return NULL;
+
+ rcu_read_lock();
+ netdev = dev->netdev;
+ if (netdev)
+ dev_hold(netdev);
+ rcu_read_unlock();
+
+ return netdev;
+}
+
+static int pvrdma_register_device(struct pvrdma_dev *dev)
+{
+ int ret = -1;
+ int i = 0;
+
+ strlcpy(dev->ib_dev.name, "vmw_pvrdma%d", IB_DEVICE_NAME_MAX);
+ dev->ib_dev.node_guid = dev->dsr->caps.node_guid;
+ dev->sys_image_guid = dev->dsr->caps.sys_image_guid;
+ dev->flags = 0;
+ dev->ib_dev.owner = THIS_MODULE;
+ dev->ib_dev.num_comp_vectors = 1;
+ dev->ib_dev.dma_device = &dev->pdev->dev;
+ dev->ib_dev.uverbs_abi_ver = PVRDMA_UVERBS_ABI_VERSION;
+ dev->ib_dev.uverbs_cmd_mask =
+ (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
+ (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_REG_MR) |
+ (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
+ (1ull << IB_USER_VERBS_CMD_POLL_CQ) |
+ (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
+ (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
+ (1ull << IB_USER_VERBS_CMD_POST_SEND) |
+ (1ull << IB_USER_VERBS_CMD_POST_RECV) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_AH) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_AH);
+
+ dev->ib_dev.node_type = RDMA_NODE_IB_CA;
+ dev->ib_dev.phys_port_cnt = dev->dsr->caps.phys_port_cnt;
+
+ dev->ib_dev.query_device = pvrdma_query_device;
+ dev->ib_dev.query_port = pvrdma_query_port;
+ dev->ib_dev.query_gid = pvrdma_query_gid;
+ dev->ib_dev.query_pkey = pvrdma_query_pkey;
+ dev->ib_dev.modify_port = pvrdma_modify_port;
+ dev->ib_dev.alloc_ucontext = pvrdma_alloc_ucontext;
+ dev->ib_dev.dealloc_ucontext = pvrdma_dealloc_ucontext;
+ dev->ib_dev.mmap = pvrdma_mmap;
+ dev->ib_dev.alloc_pd = pvrdma_alloc_pd;
+ dev->ib_dev.dealloc_pd = pvrdma_dealloc_pd;
+ dev->ib_dev.create_ah = pvrdma_create_ah;
+ dev->ib_dev.destroy_ah = pvrdma_destroy_ah;
+ dev->ib_dev.create_qp = pvrdma_create_qp;
+ dev->ib_dev.modify_qp = pvrdma_modify_qp;
+ dev->ib_dev.query_qp = pvrdma_query_qp;
+ dev->ib_dev.destroy_qp = pvrdma_destroy_qp;
+ dev->ib_dev.post_send = pvrdma_post_send;
+ dev->ib_dev.post_recv = pvrdma_post_recv;
+ dev->ib_dev.create_cq = pvrdma_create_cq;
+ dev->ib_dev.modify_cq = pvrdma_modify_cq;
+ dev->ib_dev.resize_cq = pvrdma_resize_cq;
+ dev->ib_dev.destroy_cq = pvrdma_destroy_cq;
+ dev->ib_dev.poll_cq = pvrdma_poll_cq;
+ dev->ib_dev.req_notify_cq = pvrdma_req_notify_cq;
+ dev->ib_dev.get_dma_mr = pvrdma_get_dma_mr;
+ dev->ib_dev.reg_user_mr = pvrdma_reg_user_mr;
+ dev->ib_dev.dereg_mr = pvrdma_dereg_mr;
+ dev->ib_dev.alloc_mr = pvrdma_alloc_mr;
+ dev->ib_dev.map_mr_sg = pvrdma_map_mr_sg;
+ dev->ib_dev.add_gid = pvrdma_add_gid;
+ dev->ib_dev.del_gid = pvrdma_del_gid;
+ dev->ib_dev.get_netdev = pvrdma_get_netdev;
+ dev->ib_dev.get_port_immutable = pvrdma_port_immutable;
+ dev->ib_dev.get_link_layer = pvrdma_port_link_layer;
+ dev->ib_dev.get_dev_fw_str = pvrdma_get_fw_ver_str;
+
+ mutex_init(&dev->port_mutex);
+ spin_lock_init(&dev->desc_lock);
+
+ dev->cq_tbl = kcalloc(dev->dsr->caps.max_cq, sizeof(void *),
+ GFP_KERNEL);
+ if (!dev->cq_tbl)
+ return ret;
+ spin_lock_init(&dev->cq_tbl_lock);
+
+ dev->qp_tbl = kcalloc(dev->dsr->caps.max_qp, sizeof(void *),
+ GFP_KERNEL);
+ if (!dev->qp_tbl)
+ goto err_cq_free;
+ spin_lock_init(&dev->qp_tbl_lock);
+
+ ret = ib_register_device(&dev->ib_dev, NULL);
+ if (ret)
+ goto err_qp_free;
+
+ for (i = 0; i < ARRAY_SIZE(pvrdma_class_attributes); ++i) {
+ ret = device_create_file(&dev->ib_dev.dev,
+ pvrdma_class_attributes[i]);
+ if (ret)
+ goto err_class;
+ }
+
+ dev->ib_active = true;
+
+ return 0;
+
+err_class:
+ ib_unregister_device(&dev->ib_dev);
+err_qp_free:
+ kfree(dev->qp_tbl);
+err_cq_free:
+ kfree(dev->cq_tbl);
+
+ return ret;
+}
+
+static irqreturn_t pvrdma_intr0_handler(int irq, void *dev_id)
+{
+ u32 icr = PVRDMA_INTR_CAUSE_RESPONSE;
+ struct pvrdma_dev *dev = dev_id;
+
+ dev_dbg(&dev->pdev->dev, "interrupt 0 (response) handler\n");
+
+ if (dev->intr.type != PVRDMA_INTR_TYPE_MSIX) {
+ /* Legacy intr */
+ icr = pvrdma_read_reg(dev, PVRDMA_REG_ICR);
+ if (icr == 0)
+ return IRQ_NONE;
+ }
+
+ if (icr == PVRDMA_INTR_CAUSE_RESPONSE)
+ complete(&dev->cmd_done);
+
+ return IRQ_HANDLED;
+}
+
+static void pvrdma_qp_event(struct pvrdma_dev *dev, u32 qpn, int type)
+{
+ struct pvrdma_qp *qp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->qp_tbl_lock, flags);
+ qp = dev->qp_tbl[qpn % dev->dsr->caps.max_qp];
+ if (qp)
+ atomic_inc(&qp->refcnt);
+ spin_unlock_irqrestore(&dev->qp_tbl_lock, flags);
+
+ if (qp && qp->ibqp.event_handler) {
+ struct ib_qp *ibqp = &qp->ibqp;
+ struct ib_event e;
+
+ e.device = ibqp->device;
+ e.element.qp = ibqp;
+ e.event = type; /* 1:1 mapping for now. */
+ ibqp->event_handler(&e, ibqp->qp_context);
+ }
+ if (qp) {
+ atomic_dec(&qp->refcnt);
+ if (atomic_read(&qp->refcnt) == 0)
+ wake_up(&qp->wait);
+ }
+}
+
+static void pvrdma_cq_event(struct pvrdma_dev *dev, u32 cqn, int type)
+{
+ struct pvrdma_cq *cq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->cq_tbl_lock, flags);
+ cq = dev->cq_tbl[cqn % dev->dsr->caps.max_cq];
+ if (cq)
+ atomic_inc(&cq->refcnt);
+ spin_unlock_irqrestore(&dev->cq_tbl_lock, flags);
+
+ if (cq && cq->ibcq.event_handler) {
+ struct ib_cq *ibcq = &cq->ibcq;
+ struct ib_event e;
+
+ e.device = ibcq->device;
+ e.element.cq = ibcq;
+ e.event = type; /* 1:1 mapping for now. */
+ ibcq->event_handler(&e, ibcq->cq_context);
+ }
+ if (cq) {
+ atomic_dec(&cq->refcnt);
+ if (atomic_read(&cq->refcnt) == 0)
+ wake_up(&cq->wait);
+ }
+}
+
+static void pvrdma_dispatch_event(struct pvrdma_dev *dev, int port,
+ enum ib_event_type event)
+{
+ struct ib_event ib_event;
+
+ memset(&ib_event, 0, sizeof(ib_event));
+ ib_event.device = &dev->ib_dev;
+ ib_event.element.port_num = port;
+ ib_event.event = event;
+ ib_dispatch_event(&ib_event);
+}
+
+static void pvrdma_dev_event(struct pvrdma_dev *dev, u8 port, int type)
+{
+ if (port < 1 || port > dev->dsr->caps.phys_port_cnt) {
+ dev_warn(&dev->pdev->dev, "event on port %d\n", port);
+ return;
+ }
+
+ pvrdma_dispatch_event(dev, port, type);
+}
+
+static inline struct pvrdma_eqe *get_eqe(struct pvrdma_dev *dev, unsigned int i)
+{
+ return (struct pvrdma_eqe *)pvrdma_page_dir_get_ptr(
+ &dev->async_pdir,
+ PAGE_SIZE +
+ sizeof(struct pvrdma_eqe) * i);
+}
+
+static irqreturn_t pvrdma_intr1_handler(int irq, void *dev_id)
+{
+ struct pvrdma_dev *dev = dev_id;
+ struct pvrdma_ring *ring = &dev->async_ring_state->rx;
+ int ring_slots = (dev->dsr->async_ring_pages.num_pages - 1) *
+ PAGE_SIZE / sizeof(struct pvrdma_eqe);
+ unsigned int head;
+
+ dev_dbg(&dev->pdev->dev, "interrupt 1 (async event) handler\n");
+
+ /*
+ * Don't process events until the IB device is registered. Otherwise
+ * we'll try to ib_dispatch_event() on an invalid device.
+ */
+ if (!dev->ib_active)
+ return IRQ_HANDLED;
+
+ while (pvrdma_idx_ring_has_data(ring, ring_slots, &head) > 0) {
+ struct pvrdma_eqe *eqe;
+
+ eqe = get_eqe(dev, head);
+
+ switch (eqe->type) {
+ case PVRDMA_EVENT_QP_FATAL:
+ case PVRDMA_EVENT_QP_REQ_ERR:
+ case PVRDMA_EVENT_QP_ACCESS_ERR:
+ case PVRDMA_EVENT_COMM_EST:
+ case PVRDMA_EVENT_SQ_DRAINED:
+ case PVRDMA_EVENT_PATH_MIG:
+ case PVRDMA_EVENT_PATH_MIG_ERR:
+ case PVRDMA_EVENT_QP_LAST_WQE_REACHED:
+ pvrdma_qp_event(dev, eqe->info, eqe->type);
+ break;
+
+ case PVRDMA_EVENT_CQ_ERR:
+ pvrdma_cq_event(dev, eqe->info, eqe->type);
+ break;
+
+ case PVRDMA_EVENT_SRQ_ERR:
+ case PVRDMA_EVENT_SRQ_LIMIT_REACHED:
+ break;
+
+ case PVRDMA_EVENT_PORT_ACTIVE:
+ case PVRDMA_EVENT_PORT_ERR:
+ case PVRDMA_EVENT_LID_CHANGE:
+ case PVRDMA_EVENT_PKEY_CHANGE:
+ case PVRDMA_EVENT_SM_CHANGE:
+ case PVRDMA_EVENT_CLIENT_REREGISTER:
+ case PVRDMA_EVENT_GID_CHANGE:
+ pvrdma_dev_event(dev, eqe->info, eqe->type);
+ break;
+
+ case PVRDMA_EVENT_DEVICE_FATAL:
+ pvrdma_dev_event(dev, 1, eqe->type);
+ break;
+
+ default:
+ break;
+ }
+
+ pvrdma_idx_ring_inc(&ring->cons_head, ring_slots);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static inline struct pvrdma_cqne *get_cqne(struct pvrdma_dev *dev,
+ unsigned int i)
+{
+ return (struct pvrdma_cqne *)pvrdma_page_dir_get_ptr(
+ &dev->cq_pdir,
+ PAGE_SIZE +
+ sizeof(struct pvrdma_cqne) * i);
+}
+
+static irqreturn_t pvrdma_intrx_handler(int irq, void *dev_id)
+{
+ struct pvrdma_dev *dev = dev_id;
+ struct pvrdma_ring *ring = &dev->cq_ring_state->rx;
+ int ring_slots = (dev->dsr->cq_ring_pages.num_pages - 1) * PAGE_SIZE /
+ sizeof(struct pvrdma_cqne);
+ unsigned int head;
+ unsigned long flags;
+
+ dev_dbg(&dev->pdev->dev, "interrupt x (completion) handler\n");
+
+ while (pvrdma_idx_ring_has_data(ring, ring_slots, &head) > 0) {
+ struct pvrdma_cqne *cqne;
+ struct pvrdma_cq *cq;
+
+ cqne = get_cqne(dev, head);
+ spin_lock_irqsave(&dev->cq_tbl_lock, flags);
+ cq = dev->cq_tbl[cqne->info % dev->dsr->caps.max_cq];
+ if (cq)
+ atomic_inc(&cq->refcnt);
+ spin_unlock_irqrestore(&dev->cq_tbl_lock, flags);
+
+ if (cq && cq->ibcq.comp_handler)
+ cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
+ if (cq) {
+ atomic_dec(&cq->refcnt);
+ if (atomic_read(&cq->refcnt))
+ wake_up(&cq->wait);
+ }
+ pvrdma_idx_ring_inc(&ring->cons_head, ring_slots);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void pvrdma_disable_msi_all(struct pvrdma_dev *dev)
+{
+ if (dev->intr.type == PVRDMA_INTR_TYPE_MSIX)
+ pci_disable_msix(dev->pdev);
+ else if (dev->intr.type == PVRDMA_INTR_TYPE_MSI)
+ pci_disable_msi(dev->pdev);
+}
+
+static void pvrdma_free_irq(struct pvrdma_dev *dev)
+{
+ int i;
+
+ dev_dbg(&dev->pdev->dev, "freeing interrupts\n");
+
+ if (dev->intr.type == PVRDMA_INTR_TYPE_MSIX) {
+ for (i = 0; i < dev->intr.size; i++) {
+ if (dev->intr.enabled[i]) {
+ free_irq(dev->intr.msix_entry[i].vector, dev);
+ dev->intr.enabled[i] = 0;
+ }
+ }
+ } else if (dev->intr.type == PVRDMA_INTR_TYPE_INTX ||
+ dev->intr.type == PVRDMA_INTR_TYPE_MSI) {
+ free_irq(dev->pdev->irq, dev);
+ }
+}
+
+static void pvrdma_enable_intrs(struct pvrdma_dev *dev)
+{
+ dev_dbg(&dev->pdev->dev, "enable interrupts\n");
+ pvrdma_write_reg(dev, PVRDMA_REG_IMR, 0);
+}
+
+static void pvrdma_disable_intrs(struct pvrdma_dev *dev)
+{
+ dev_dbg(&dev->pdev->dev, "disable interrupts\n");
+ pvrdma_write_reg(dev, PVRDMA_REG_IMR, ~0);
+}
+
+static int pvrdma_enable_msix(struct pci_dev *pdev, struct pvrdma_dev *dev)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < PVRDMA_MAX_INTERRUPTS; i++) {
+ dev->intr.msix_entry[i].entry = i;
+ dev->intr.msix_entry[i].vector = i;
+
+ switch (i) {
+ case 0:
+ /* CMD ring handler */
+ dev->intr.handler[i] = pvrdma_intr0_handler;
+ break;
+ case 1:
+ /* Async event ring handler */
+ dev->intr.handler[i] = pvrdma_intr1_handler;
+ break;
+ default:
+ /* Completion queue handler */
+ dev->intr.handler[i] = pvrdma_intrx_handler;
+ break;
+ }
+ }
+
+ ret = pci_enable_msix(pdev, dev->intr.msix_entry,
+ PVRDMA_MAX_INTERRUPTS);
+ if (!ret) {
+ dev->intr.type = PVRDMA_INTR_TYPE_MSIX;
+ dev->intr.size = PVRDMA_MAX_INTERRUPTS;
+ } else if (ret > 0) {
+ ret = pci_enable_msix(pdev, dev->intr.msix_entry, ret);
+ if (!ret) {
+ dev->intr.type = PVRDMA_INTR_TYPE_MSIX;
+ dev->intr.size = ret;
+ } else {
+ dev->intr.size = 0;
+ }
+ }
+
+ dev_dbg(&pdev->dev, "using interrupt type %d, size %d\n",
+ dev->intr.type, dev->intr.size);
+
+ return ret;
+}
+
+static int pvrdma_alloc_intrs(struct pvrdma_dev *dev)
+{
+ int ret = 0;
+ int i;
+
+ if (pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX) &&
+ pvrdma_enable_msix(dev->pdev, dev)) {
+ /* Try MSI */
+ ret = pci_enable_msi(dev->pdev);
+ if (!ret) {
+ dev->intr.type = PVRDMA_INTR_TYPE_MSI;
+ } else {
+ /* Legacy INTR */
+ dev->intr.type = PVRDMA_INTR_TYPE_INTX;
+ }
+ }
+
+ /* Request First IRQ */
+ switch (dev->intr.type) {
+ case PVRDMA_INTR_TYPE_INTX:
+ case PVRDMA_INTR_TYPE_MSI:
+ ret = request_irq(dev->pdev->irq, pvrdma_intr0_handler,
+ IRQF_SHARED, DRV_NAME, dev);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "failed to request interrupt\n");
+ goto disable_msi;
+ }
+ break;
+ case PVRDMA_INTR_TYPE_MSIX:
+ ret = request_irq(dev->intr.msix_entry[0].vector,
+ pvrdma_intr0_handler, 0, DRV_NAME, dev);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "failed to request interrupt 0\n");
+ goto disable_msi;
+ }
+ dev->intr.enabled[0] = 1;
+ break;
+ default:
+ /* Not reached */
+ break;
+ }
+
+ /* For MSIX: request intr for each vector */
+ if (dev->intr.size > 1) {
+ ret = request_irq(dev->intr.msix_entry[1].vector,
+ pvrdma_intr1_handler, 0, DRV_NAME, dev);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "failed to request interrupt 1\n");
+ goto free_irq;
+ }
+ dev->intr.enabled[1] = 1;
+
+ for (i = 2; i < dev->intr.size; i++) {
+ ret = request_irq(dev->intr.msix_entry[i].vector,
+ pvrdma_intrx_handler, 0,
+ DRV_NAME, dev);
+ if (ret) {
+ dev_err(&dev->pdev->dev,
+ "failed to request interrupt %d\n", i);
+ goto free_irq;
+ }
+ dev->intr.enabled[i] = 1;
+ }
+ }
+
+ return 0;
+
+free_irq:
+ pvrdma_free_irq(dev);
+disable_msi:
+ pvrdma_disable_msi_all(dev);
+ return ret;
+}
+
+static void pvrdma_free_slots(struct pvrdma_dev *dev)
+{
+ struct pci_dev *pdev = dev->pdev;
+
+ if (dev->resp_slot)
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->resp_slot,
+ dev->dsr->resp_slot_dma);
+ if (dev->cmd_slot)
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->cmd_slot,
+ dev->dsr->cmd_slot_dma);
+}
+
+static int pvrdma_add_gid_at_index(struct pvrdma_dev *dev,
+ const union ib_gid *gid,
+ int index)
+{
+ int ret;
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_create_bind *cmd_bind = &req.create_bind;
+
+ if (!dev->sgid_tbl) {
+ dev_warn(&dev->pdev->dev, "sgid table not initialized\n");
+ return -EINVAL;
+ }
+
+ memset(cmd_bind, 0, sizeof(*cmd_bind));
+ cmd_bind->hdr.cmd = PVRDMA_CMD_CREATE_BIND;
+ memcpy(cmd_bind->new_gid, gid->raw, 16);
+ cmd_bind->mtu = ib_mtu_enum_to_int(IB_MTU_1024);
+ cmd_bind->vlan = 0xfff;
+ cmd_bind->index = index;
+ cmd_bind->gid_type = PVRDMA_GID_TYPE_FLAG_ROCE_V1;
+
+ ret = pvrdma_cmd_post(dev, &req, NULL, 0);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not create binding, error: %d\n", ret);
+ return -EFAULT;
+ }
+ memcpy(&dev->sgid_tbl[index], gid, sizeof(*gid));
+ return 0;
+}
+
+static int pvrdma_add_gid(struct ib_device *ibdev,
+ u8 port_num,
+ unsigned int index,
+ const union ib_gid *gid,
+ const struct ib_gid_attr *attr,
+ void **context)
+{
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+
+ return pvrdma_add_gid_at_index(dev, gid, index);
+}
+
+static int pvrdma_del_gid_at_index(struct pvrdma_dev *dev, int index)
+{
+ int ret;
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_destroy_bind *cmd_dest = &req.destroy_bind;
+
+ /* Update sgid table. */
+ if (!dev->sgid_tbl) {
+ dev_warn(&dev->pdev->dev, "sgid table not initialized\n");
+ return -EINVAL;
+ }
+
+ memset(cmd_dest, 0, sizeof(*cmd_dest));
+ cmd_dest->hdr.cmd = PVRDMA_CMD_DESTROY_BIND;
+ memcpy(cmd_dest->dest_gid, &dev->sgid_tbl[index], 16);
+ cmd_dest->index = index;
+
+ ret = pvrdma_cmd_post(dev, &req, NULL, 0);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not destroy binding, error: %d\n", ret);
+ return ret;
+ }
+ memset(&dev->sgid_tbl[index], 0, 16);
+ return 0;
+}
+
+static int pvrdma_del_gid(struct ib_device *ibdev,
+ u8 port_num,
+ unsigned int index,
+ void **context)
+{
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+
+ dev_dbg(&dev->pdev->dev, "removing gid at index %u from %s",
+ index, dev->netdev->name);
+
+ return pvrdma_del_gid_at_index(dev, index);
+}
+
+static void pvrdma_netdevice_event_handle(struct pvrdma_dev *dev,
+ unsigned long event)
+{
+ switch (event) {
+ case NETDEV_REBOOT:
+ case NETDEV_DOWN:
+ pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ERR);
+ break;
+ case NETDEV_UP:
+ pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ACTIVE);
+ break;
+ default:
+ dev_dbg(&dev->pdev->dev, "ignore netdevice event %ld on %s\n",
+ event, dev->ib_dev.name);
+ break;
+ }
+}
+
+static void pvrdma_netdevice_event_work(struct work_struct *work)
+{
+ struct pvrdma_netdevice_work *netdev_work;
+ struct pvrdma_dev *dev;
+
+ netdev_work = container_of(work, struct pvrdma_netdevice_work, work);
+
+ mutex_lock(&pvrdma_device_list_lock);
+ list_for_each_entry(dev, &pvrdma_device_list, device_link) {
+ if (dev->netdev == netdev_work->event_netdev) {
+ pvrdma_netdevice_event_handle(dev, netdev_work->event);
+ break;
+ }
+ }
+ mutex_unlock(&pvrdma_device_list_lock);
+
+ kfree(netdev_work);
+}
+
+static int pvrdma_netdevice_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *event_netdev = netdev_notifier_info_to_dev(ptr);
+ struct pvrdma_netdevice_work *netdev_work;
+
+ netdev_work = kmalloc(sizeof(*netdev_work), GFP_ATOMIC);
+ if (!netdev_work)
+ return NOTIFY_BAD;
+
+ INIT_WORK(&netdev_work->work, pvrdma_netdevice_event_work);
+ netdev_work->event_netdev = event_netdev;
+ netdev_work->event = event;
+ queue_work(event_wq, &netdev_work->work);
+
+ return NOTIFY_DONE;
+}
+
+static int pvrdma_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct pci_dev *pdev_net;
+ struct pvrdma_dev *dev;
+ int ret;
+ unsigned long start;
+ unsigned long len;
+ unsigned int version;
+ dma_addr_t slot_dma = 0;
+
+ dev_dbg(&pdev->dev, "initializing driver %s\n", pci_name(pdev));
+
+ /* Allocate zero-out device */
+ dev = (struct pvrdma_dev *)ib_alloc_device(sizeof(*dev));
+ if (!dev) {
+ dev_err(&pdev->dev, "failed to allocate IB device\n");
+ return -ENOMEM;
+ }
+
+ mutex_lock(&pvrdma_device_list_lock);
+ list_add(&dev->device_link, &pvrdma_device_list);
+ mutex_unlock(&pvrdma_device_list_lock);
+
+ ret = pvrdma_init_device(dev);
+ if (ret)
+ goto err_free_device;
+
+ dev->pdev = pdev;
+ pci_set_drvdata(pdev, dev);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ goto err_free_device;
+ }
+
+ dev_dbg(&pdev->dev, "PCI resource flags BAR0 %#lx\n",
+ pci_resource_flags(pdev, 0));
+ dev_dbg(&pdev->dev, "PCI resource len %#llx\n",
+ (unsigned long long)pci_resource_len(pdev, 0));
+ dev_dbg(&pdev->dev, "PCI resource start %#llx\n",
+ (unsigned long long)pci_resource_start(pdev, 0));
+ dev_dbg(&pdev->dev, "PCI resource flags BAR1 %#lx\n",
+ pci_resource_flags(pdev, 1));
+ dev_dbg(&pdev->dev, "PCI resource len %#llx\n",
+ (unsigned long long)pci_resource_len(pdev, 1));
+ dev_dbg(&pdev->dev, "PCI resource start %#llx\n",
+ (unsigned long long)pci_resource_start(pdev, 1));
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
+ !(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
+ dev_err(&pdev->dev, "PCI BAR region not MMIO\n");
+ ret = -ENOMEM;
+ goto err_free_device;
+ }
+
+ ret = pci_request_regions(pdev, DRV_NAME);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot request PCI resources\n");
+ goto err_disable_pdev;
+ }
+
+ /* Enable 64-Bit DMA */
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
+ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ if (ret != 0) {
+ dev_err(&pdev->dev,
+ "pci_set_consistent_dma_mask failed\n");
+ goto err_free_resource;
+ }
+ } else {
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (ret != 0) {
+ dev_err(&pdev->dev,
+ "pci_set_dma_mask failed\n");
+ goto err_free_resource;
+ }
+ }
+
+ pci_set_master(pdev);
+
+ /* Map register space */
+ start = pci_resource_start(dev->pdev, PVRDMA_PCI_RESOURCE_REG);
+ len = pci_resource_len(dev->pdev, PVRDMA_PCI_RESOURCE_REG);
+ dev->regs = ioremap(start, len);
+ if (!dev->regs) {
+ dev_err(&pdev->dev, "register mapping failed\n");
+ ret = -ENOMEM;
+ goto err_free_resource;
+ }
+
+ /* Setup per-device UAR. */
+ dev->driver_uar.index = 0;
+ dev->driver_uar.pfn =
+ pci_resource_start(dev->pdev, PVRDMA_PCI_RESOURCE_UAR) >>
+ PAGE_SHIFT;
+ dev->driver_uar.map =
+ ioremap(dev->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
+ if (!dev->driver_uar.map) {
+ dev_err(&pdev->dev, "failed to remap UAR pages\n");
+ ret = -ENOMEM;
+ goto err_unmap_regs;
+ }
+
+ version = pvrdma_read_reg(dev, PVRDMA_REG_VERSION);
+ dev_info(&pdev->dev, "device version %d, driver version %d\n",
+ version, PVRDMA_VERSION);
+ if (version < PVRDMA_VERSION) {
+ dev_err(&pdev->dev, "incompatible device version\n");
+ goto err_uar_unmap;
+ }
+
+ dev->dsr = dma_alloc_coherent(&pdev->dev, sizeof(*dev->dsr),
+ &dev->dsrbase, GFP_KERNEL);
+ if (!dev->dsr) {
+ dev_err(&pdev->dev, "failed to allocate shared region\n");
+ ret = -ENOMEM;
+ goto err_uar_unmap;
+ }
+
+ /* Setup the shared region */
+ memset(dev->dsr, 0, sizeof(*dev->dsr));
+ dev->dsr->driver_version = PVRDMA_VERSION;
+ dev->dsr->gos_info.gos_bits = sizeof(void *) == 4 ?
+ PVRDMA_GOS_BITS_32 :
+ PVRDMA_GOS_BITS_64;
+ dev->dsr->gos_info.gos_type = PVRDMA_GOS_TYPE_LINUX;
+ dev->dsr->gos_info.gos_ver = 1;
+ dev->dsr->uar_pfn = dev->driver_uar.pfn;
+
+ /* Command slot. */
+ dev->cmd_slot = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ &slot_dma, GFP_KERNEL);
+ if (!dev->cmd_slot) {
+ ret = -ENOMEM;
+ goto err_free_dsr;
+ }
+
+ dev->dsr->cmd_slot_dma = (u64)slot_dma;
+
+ /* Response slot. */
+ dev->resp_slot = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ &slot_dma, GFP_KERNEL);
+ if (!dev->resp_slot) {
+ ret = -ENOMEM;
+ goto err_free_slots;
+ }
+
+ dev->dsr->resp_slot_dma = (u64)slot_dma;
+
+ /* Async event ring */
+ dev->dsr->async_ring_pages.num_pages = 4;
+ ret = pvrdma_page_dir_init(dev, &dev->async_pdir,
+ dev->dsr->async_ring_pages.num_pages, true);
+ if (ret)
+ goto err_free_slots;
+ dev->async_ring_state = dev->async_pdir.pages[0];
+ dev->dsr->async_ring_pages.pdir_dma = dev->async_pdir.dir_dma;
+
+ /* CQ notification ring */
+ dev->dsr->cq_ring_pages.num_pages = 4;
+ ret = pvrdma_page_dir_init(dev, &dev->cq_pdir,
+ dev->dsr->cq_ring_pages.num_pages, true);
+ if (ret)
+ goto err_free_async_ring;
+ dev->cq_ring_state = dev->cq_pdir.pages[0];
+ dev->dsr->cq_ring_pages.pdir_dma = dev->cq_pdir.dir_dma;
+
+ /*
+ * Write the PA of the shared region to the device. The writes must be
+ * ordered such that the high bits are written last. When the writes
+ * complete, the device will have filled out the capabilities.
+ */
+
+ pvrdma_write_reg(dev, PVRDMA_REG_DSRLOW, (u32)dev->dsrbase);
+ pvrdma_write_reg(dev, PVRDMA_REG_DSRHIGH,
+ (u32)((u64)(dev->dsrbase) >> 32));
+
+ /* Make sure the write is complete before reading status. */
+ mb();
+
+ /* Currently, the driver only supports RoCE mode. */
+ if (dev->dsr->caps.mode != PVRDMA_DEVICE_MODE_ROCE) {
+ dev_err(&pdev->dev, "unsupported transport %d\n",
+ dev->dsr->caps.mode);
+ ret = -EFAULT;
+ goto err_free_cq_ring;
+ }
+
+ /* Currently, the driver only supports RoCE V1. */
+ if (!(dev->dsr->caps.gid_types & PVRDMA_GID_TYPE_FLAG_ROCE_V1)) {
+ dev_err(&pdev->dev, "driver needs RoCE v1 support\n");
+ ret = -EFAULT;
+ goto err_free_cq_ring;
+ }
+
+ /* Paired vmxnet3 will have same bus, slot. But func will be 0 */
+ pdev_net = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
+ if (!pdev_net) {
+ dev_err(&pdev->dev, "failed to find paired net device\n");
+ ret = -ENODEV;
+ goto err_free_cq_ring;
+ }
+
+ if (pdev_net->vendor != PCI_VENDOR_ID_VMWARE ||
+ pdev_net->device != PCI_DEVICE_ID_VMWARE_VMXNET3) {
+ dev_err(&pdev->dev, "failed to find paired vmxnet3 device\n");
+ pci_dev_put(pdev_net);
+ ret = -ENODEV;
+ goto err_free_cq_ring;
+ }
+
+ dev->netdev = pci_get_drvdata(pdev_net);
+ pci_dev_put(pdev_net);
+ if (!dev->netdev) {
+ dev_err(&pdev->dev, "failed to get vmxnet3 device\n");
+ ret = -ENODEV;
+ goto err_free_cq_ring;
+ }
+
+ dev_info(&pdev->dev, "paired device to %s\n", dev->netdev->name);
+
+ /* Interrupt setup */
+ ret = pvrdma_alloc_intrs(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to allocate interrupts\n");
+ ret = -ENOMEM;
+ goto err_netdevice;
+ }
+
+ /* Allocate UAR table. */
+ ret = pvrdma_uar_table_init(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to allocate UAR table\n");
+ ret = -ENOMEM;
+ goto err_free_intrs;
+ }
+
+ /* Allocate GID table */
+ dev->sgid_tbl = kcalloc(dev->dsr->caps.gid_tbl_len,
+ sizeof(union ib_gid), GFP_KERNEL);
+ if (!dev->sgid_tbl) {
+ ret = -ENOMEM;
+ goto err_free_uar_table;
+ }
+ dev_dbg(&pdev->dev, "gid table len %d\n", dev->dsr->caps.gid_tbl_len);
+
+ pvrdma_enable_intrs(dev);
+
+ /* Activate pvrdma device */
+ pvrdma_write_reg(dev, PVRDMA_REG_CTL, PVRDMA_DEVICE_CTL_ACTIVATE);
+
+ /* Make sure the write is complete before reading status. */
+ mb();
+
+ /* Check if device was successfully activated */
+ ret = pvrdma_read_reg(dev, PVRDMA_REG_ERR);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to activate device\n");
+ ret = -EFAULT;
+ goto err_disable_intr;
+ }
+
+ /* Register IB device */
+ ret = pvrdma_register_device(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register IB device\n");
+ goto err_disable_intr;
+ }
+
+ dev->nb_netdev.notifier_call = pvrdma_netdevice_event;
+ ret = register_netdevice_notifier(&dev->nb_netdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register netdevice events\n");
+ goto err_unreg_ibdev;
+ }
+
+ dev_info(&pdev->dev, "attached to device\n");
+ return 0;
+
+err_unreg_ibdev:
+ ib_unregister_device(&dev->ib_dev);
+err_disable_intr:
+ pvrdma_disable_intrs(dev);
+ kfree(dev->sgid_tbl);
+err_free_uar_table:
+ pvrdma_uar_table_cleanup(dev);
+err_free_intrs:
+ pvrdma_free_irq(dev);
+ pvrdma_disable_msi_all(dev);
+err_netdevice:
+ unregister_netdevice_notifier(&dev->nb_netdev);
+err_free_cq_ring:
+ pvrdma_page_dir_cleanup(dev, &dev->cq_pdir);
+err_free_async_ring:
+ pvrdma_page_dir_cleanup(dev, &dev->async_pdir);
+err_free_slots:
+ pvrdma_free_slots(dev);
+err_free_dsr:
+ dma_free_coherent(&pdev->dev, sizeof(*dev->dsr), dev->dsr,
+ dev->dsrbase);
+err_uar_unmap:
+ iounmap(dev->driver_uar.map);
+err_unmap_regs:
+ iounmap(dev->regs);
+err_free_resource:
+ pci_release_regions(pdev);
+err_disable_pdev:
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+err_free_device:
+ mutex_lock(&pvrdma_device_list_lock);
+ list_del(&dev->device_link);
+ mutex_unlock(&pvrdma_device_list_lock);
+ ib_dealloc_device(&dev->ib_dev);
+ return ret;
+}
+
+static void pvrdma_pci_remove(struct pci_dev *pdev)
+{
+ struct pvrdma_dev *dev = pci_get_drvdata(pdev);
+
+ if (!dev)
+ return;
+
+ dev_info(&pdev->dev, "detaching from device\n");
+
+ unregister_netdevice_notifier(&dev->nb_netdev);
+ dev->nb_netdev.notifier_call = NULL;
+
+ flush_workqueue(event_wq);
+
+ /* Unregister ib device */
+ ib_unregister_device(&dev->ib_dev);
+
+ mutex_lock(&pvrdma_device_list_lock);
+ list_del(&dev->device_link);
+ mutex_unlock(&pvrdma_device_list_lock);
+
+ pvrdma_disable_intrs(dev);
+ pvrdma_free_irq(dev);
+ pvrdma_disable_msi_all(dev);
+
+ /* Deactivate pvrdma device */
+ pvrdma_write_reg(dev, PVRDMA_REG_CTL, PVRDMA_DEVICE_CTL_RESET);
+ pvrdma_page_dir_cleanup(dev, &dev->cq_pdir);
+ pvrdma_page_dir_cleanup(dev, &dev->async_pdir);
+ pvrdma_free_slots(dev);
+
+ iounmap(dev->regs);
+ kfree(dev->sgid_tbl);
+ kfree(dev->cq_tbl);
+ kfree(dev->qp_tbl);
+ pvrdma_uar_table_cleanup(dev);
+ iounmap(dev->driver_uar.map);
+
+ ib_dealloc_device(&dev->ib_dev);
+
+ /* Free pci resources */
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+static struct pci_device_id pvrdma_pci_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_PVRDMA), },
+ { 0 },
+};
+
+MODULE_DEVICE_TABLE(pci, pvrdma_pci_table);
+
+static struct pci_driver pvrdma_driver = {
+ .name = DRV_NAME,
+ .id_table = pvrdma_pci_table,
+ .probe = pvrdma_pci_probe,
+ .remove = pvrdma_pci_remove,
+};
+
+static int __init pvrdma_init(void)
+{
+ int err;
+
+ event_wq = alloc_ordered_workqueue("pvrdma_event_wq", WQ_MEM_RECLAIM);
+ if (!event_wq)
+ return -ENOMEM;
+
+ err = pci_register_driver(&pvrdma_driver);
+ if (err)
+ destroy_workqueue(event_wq);
+
+ return err;
+}
+
+static void __exit pvrdma_cleanup(void)
+{
+ pci_unregister_driver(&pvrdma_driver);
+
+ destroy_workqueue(event_wq);
+}
+
+module_init(pvrdma_init);
+module_exit(pvrdma_cleanup);
+
+MODULE_AUTHOR("VMware, Inc");
+MODULE_DESCRIPTION("VMware Paravirtual RDMA driver");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c
new file mode 100644
index 000000000000..948b5ccd2a70
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/bitmap.h>
+
+#include "pvrdma.h"
+
+int pvrdma_page_dir_init(struct pvrdma_dev *dev, struct pvrdma_page_dir *pdir,
+ u64 npages, bool alloc_pages)
+{
+ u64 i;
+
+ if (npages > PVRDMA_PAGE_DIR_MAX_PAGES)
+ return -EINVAL;
+
+ memset(pdir, 0, sizeof(*pdir));
+
+ pdir->dir = dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
+ &pdir->dir_dma, GFP_KERNEL);
+ if (!pdir->dir)
+ goto err;
+
+ pdir->ntables = PVRDMA_PAGE_DIR_TABLE(npages - 1) + 1;
+ pdir->tables = kcalloc(pdir->ntables, sizeof(*pdir->tables),
+ GFP_KERNEL);
+ if (!pdir->tables)
+ goto err;
+
+ for (i = 0; i < pdir->ntables; i++) {
+ pdir->tables[i] = dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
+ (dma_addr_t *)&pdir->dir[i],
+ GFP_KERNEL);
+ if (!pdir->tables[i])
+ goto err;
+ }
+
+ pdir->npages = npages;
+
+ if (alloc_pages) {
+ pdir->pages = kcalloc(npages, sizeof(*pdir->pages),
+ GFP_KERNEL);
+ if (!pdir->pages)
+ goto err;
+
+ for (i = 0; i < pdir->npages; i++) {
+ dma_addr_t page_dma;
+
+ pdir->pages[i] = dma_alloc_coherent(&dev->pdev->dev,
+ PAGE_SIZE,
+ &page_dma,
+ GFP_KERNEL);
+ if (!pdir->pages[i])
+ goto err;
+
+ pvrdma_page_dir_insert_dma(pdir, i, page_dma);
+ }
+ }
+
+ return 0;
+
+err:
+ pvrdma_page_dir_cleanup(dev, pdir);
+
+ return -ENOMEM;
+}
+
+static u64 *pvrdma_page_dir_table(struct pvrdma_page_dir *pdir, u64 idx)
+{
+ return pdir->tables[PVRDMA_PAGE_DIR_TABLE(idx)];
+}
+
+dma_addr_t pvrdma_page_dir_get_dma(struct pvrdma_page_dir *pdir, u64 idx)
+{
+ return pvrdma_page_dir_table(pdir, idx)[PVRDMA_PAGE_DIR_PAGE(idx)];
+}
+
+static void pvrdma_page_dir_cleanup_pages(struct pvrdma_dev *dev,
+ struct pvrdma_page_dir *pdir)
+{
+ if (pdir->pages) {
+ u64 i;
+
+ for (i = 0; i < pdir->npages && pdir->pages[i]; i++) {
+ dma_addr_t page_dma = pvrdma_page_dir_get_dma(pdir, i);
+
+ dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+ pdir->pages[i], page_dma);
+ }
+
+ kfree(pdir->pages);
+ }
+}
+
+static void pvrdma_page_dir_cleanup_tables(struct pvrdma_dev *dev,
+ struct pvrdma_page_dir *pdir)
+{
+ if (pdir->tables) {
+ int i;
+
+ pvrdma_page_dir_cleanup_pages(dev, pdir);
+
+ for (i = 0; i < pdir->ntables; i++) {
+ u64 *table = pdir->tables[i];
+
+ if (table)
+ dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+ table, pdir->dir[i]);
+ }
+
+ kfree(pdir->tables);
+ }
+}
+
+void pvrdma_page_dir_cleanup(struct pvrdma_dev *dev,
+ struct pvrdma_page_dir *pdir)
+{
+ if (pdir->dir) {
+ pvrdma_page_dir_cleanup_tables(dev, pdir);
+ dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+ pdir->dir, pdir->dir_dma);
+ }
+}
+
+int pvrdma_page_dir_insert_dma(struct pvrdma_page_dir *pdir, u64 idx,
+ dma_addr_t daddr)
+{
+ u64 *table;
+
+ if (idx >= pdir->npages)
+ return -EINVAL;
+
+ table = pvrdma_page_dir_table(pdir, idx);
+ table[PVRDMA_PAGE_DIR_PAGE(idx)] = daddr;
+
+ return 0;
+}
+
+int pvrdma_page_dir_insert_umem(struct pvrdma_page_dir *pdir,
+ struct ib_umem *umem, u64 offset)
+{
+ u64 i = offset;
+ int j, entry;
+ int ret = 0, len = 0;
+ struct scatterlist *sg;
+
+ if (offset >= pdir->npages)
+ return -EINVAL;
+
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) {
+ len = sg_dma_len(sg) >> PAGE_SHIFT;
+ for (j = 0; j < len; j++) {
+ dma_addr_t addr = sg_dma_address(sg) +
+ umem->page_size * j;
+
+ ret = pvrdma_page_dir_insert_dma(pdir, i, addr);
+ if (ret)
+ goto exit;
+
+ i++;
+ }
+ }
+
+exit:
+ return ret;
+}
+
+int pvrdma_page_dir_insert_page_list(struct pvrdma_page_dir *pdir,
+ u64 *page_list,
+ int num_pages)
+{
+ int i;
+ int ret;
+
+ if (num_pages > pdir->npages)
+ return -EINVAL;
+
+ for (i = 0; i < num_pages; i++) {
+ ret = pvrdma_page_dir_insert_dma(pdir, i, page_list[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+void pvrdma_qp_cap_to_ib(struct ib_qp_cap *dst, const struct pvrdma_qp_cap *src)
+{
+ dst->max_send_wr = src->max_send_wr;
+ dst->max_recv_wr = src->max_recv_wr;
+ dst->max_send_sge = src->max_send_sge;
+ dst->max_recv_sge = src->max_recv_sge;
+ dst->max_inline_data = src->max_inline_data;
+}
+
+void ib_qp_cap_to_pvrdma(struct pvrdma_qp_cap *dst, const struct ib_qp_cap *src)
+{
+ dst->max_send_wr = src->max_send_wr;
+ dst->max_recv_wr = src->max_recv_wr;
+ dst->max_send_sge = src->max_send_sge;
+ dst->max_recv_sge = src->max_recv_sge;
+ dst->max_inline_data = src->max_inline_data;
+}
+
+void pvrdma_gid_to_ib(union ib_gid *dst, const union pvrdma_gid *src)
+{
+ BUILD_BUG_ON(sizeof(union pvrdma_gid) != sizeof(union ib_gid));
+ memcpy(dst, src, sizeof(*src));
+}
+
+void ib_gid_to_pvrdma(union pvrdma_gid *dst, const union ib_gid *src)
+{
+ BUILD_BUG_ON(sizeof(union pvrdma_gid) != sizeof(union ib_gid));
+ memcpy(dst, src, sizeof(*src));
+}
+
+void pvrdma_global_route_to_ib(struct ib_global_route *dst,
+ const struct pvrdma_global_route *src)
+{
+ pvrdma_gid_to_ib(&dst->dgid, &src->dgid);
+ dst->flow_label = src->flow_label;
+ dst->sgid_index = src->sgid_index;
+ dst->hop_limit = src->hop_limit;
+ dst->traffic_class = src->traffic_class;
+}
+
+void ib_global_route_to_pvrdma(struct pvrdma_global_route *dst,
+ const struct ib_global_route *src)
+{
+ ib_gid_to_pvrdma(&dst->dgid, &src->dgid);
+ dst->flow_label = src->flow_label;
+ dst->sgid_index = src->sgid_index;
+ dst->hop_limit = src->hop_limit;
+ dst->traffic_class = src->traffic_class;
+}
+
+void pvrdma_ah_attr_to_ib(struct ib_ah_attr *dst,
+ const struct pvrdma_ah_attr *src)
+{
+ pvrdma_global_route_to_ib(&dst->grh, &src->grh);
+ dst->dlid = src->dlid;
+ dst->sl = src->sl;
+ dst->src_path_bits = src->src_path_bits;
+ dst->static_rate = src->static_rate;
+ dst->ah_flags = src->ah_flags;
+ dst->port_num = src->port_num;
+ memcpy(&dst->dmac, &src->dmac, sizeof(dst->dmac));
+}
+
+void ib_ah_attr_to_pvrdma(struct pvrdma_ah_attr *dst,
+ const struct ib_ah_attr *src)
+{
+ ib_global_route_to_pvrdma(&dst->grh, &src->grh);
+ dst->dlid = src->dlid;
+ dst->sl = src->sl;
+ dst->src_path_bits = src->src_path_bits;
+ dst->static_rate = src->static_rate;
+ dst->ah_flags = src->ah_flags;
+ dst->port_num = src->port_num;
+ memcpy(&dst->dmac, &src->dmac, sizeof(dst->dmac));
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
new file mode 100644
index 000000000000..8519f3212e52
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include "pvrdma.h"
+
+/**
+ * pvrdma_get_dma_mr - get a DMA memory region
+ * @pd: protection domain
+ * @acc: access flags
+ *
+ * @return: ib_mr pointer on success, otherwise returns an errno.
+ */
+struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc)
+{
+ struct pvrdma_dev *dev = to_vdev(pd->device);
+ struct pvrdma_user_mr *mr;
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_mr *cmd = &req.create_mr;
+ struct pvrdma_cmd_create_mr_resp *resp = &rsp.create_mr_resp;
+ int ret;
+
+ /* Support only LOCAL_WRITE flag for DMA MRs */
+ if (acc & ~IB_ACCESS_LOCAL_WRITE) {
+ dev_warn(&dev->pdev->dev,
+ "unsupported dma mr access flags %#x\n", acc);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+ if (!mr)
+ return ERR_PTR(-ENOMEM);
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_MR;
+ cmd->pd_handle = to_vpd(pd)->pd_handle;
+ cmd->access_flags = acc;
+ cmd->flags = PVRDMA_MR_FLAG_DMA;
+
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_MR_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not get DMA mem region, error: %d\n", ret);
+ kfree(mr);
+ return ERR_PTR(ret);
+ }
+
+ mr->mmr.mr_handle = resp->mr_handle;
+ mr->ibmr.lkey = resp->lkey;
+ mr->ibmr.rkey = resp->rkey;
+
+ return &mr->ibmr;
+}
+
+/**
+ * pvrdma_reg_user_mr - register a userspace memory region
+ * @pd: protection domain
+ * @start: starting address
+ * @length: length of region
+ * @virt_addr: I/O virtual address
+ * @access_flags: access flags for memory region
+ * @udata: user data
+ *
+ * @return: ib_mr pointer on success, otherwise returns an errno.
+ */
+struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ u64 virt_addr, int access_flags,
+ struct ib_udata *udata)
+{
+ struct pvrdma_dev *dev = to_vdev(pd->device);
+ struct pvrdma_user_mr *mr = NULL;
+ struct ib_umem *umem;
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_mr *cmd = &req.create_mr;
+ struct pvrdma_cmd_create_mr_resp *resp = &rsp.create_mr_resp;
+ int nchunks;
+ int ret;
+ int entry;
+ struct scatterlist *sg;
+
+ if (length == 0 || length > dev->dsr->caps.max_mr_size) {
+ dev_warn(&dev->pdev->dev, "invalid mem region length\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ umem = ib_umem_get(pd->uobject->context, start,
+ length, access_flags, 0);
+ if (IS_ERR(umem)) {
+ dev_warn(&dev->pdev->dev,
+ "could not get umem for mem region\n");
+ return ERR_CAST(umem);
+ }
+
+ nchunks = 0;
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry)
+ nchunks += sg_dma_len(sg) >> PAGE_SHIFT;
+
+ if (nchunks < 0 || nchunks > PVRDMA_PAGE_DIR_MAX_PAGES) {
+ dev_warn(&dev->pdev->dev, "overflow %d pages in mem region\n",
+ nchunks);
+ ret = -EINVAL;
+ goto err_umem;
+ }
+
+ mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+ if (!mr) {
+ ret = -ENOMEM;
+ goto err_umem;
+ }
+
+ mr->mmr.iova = virt_addr;
+ mr->mmr.size = length;
+ mr->umem = umem;
+
+ ret = pvrdma_page_dir_init(dev, &mr->pdir, nchunks, false);
+ if (ret) {
+ dev_warn(&dev->pdev->dev,
+ "could not allocate page directory\n");
+ goto err_umem;
+ }
+
+ ret = pvrdma_page_dir_insert_umem(&mr->pdir, mr->umem, 0);
+ if (ret)
+ goto err_pdir;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_MR;
+ cmd->start = start;
+ cmd->length = length;
+ cmd->pd_handle = to_vpd(pd)->pd_handle;
+ cmd->access_flags = access_flags;
+ cmd->nchunks = nchunks;
+ cmd->pdir_dma = mr->pdir.dir_dma;
+
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_MR_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not register mem region, error: %d\n", ret);
+ goto err_pdir;
+ }
+
+ mr->mmr.mr_handle = resp->mr_handle;
+ mr->ibmr.lkey = resp->lkey;
+ mr->ibmr.rkey = resp->rkey;
+
+ return &mr->ibmr;
+
+err_pdir:
+ pvrdma_page_dir_cleanup(dev, &mr->pdir);
+err_umem:
+ ib_umem_release(umem);
+ kfree(mr);
+
+ return ERR_PTR(ret);
+}
+
+/**
+ * pvrdma_alloc_mr - allocate a memory region
+ * @pd: protection domain
+ * @mr_type: type of memory region
+ * @max_num_sg: maximum number of pages
+ *
+ * @return: ib_mr pointer on success, otherwise returns an errno.
+ */
+struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+ u32 max_num_sg)
+{
+ struct pvrdma_dev *dev = to_vdev(pd->device);
+ struct pvrdma_user_mr *mr;
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_mr *cmd = &req.create_mr;
+ struct pvrdma_cmd_create_mr_resp *resp = &rsp.create_mr_resp;
+ int size = max_num_sg * sizeof(u64);
+ int ret;
+
+ if (mr_type != IB_MR_TYPE_MEM_REG ||
+ max_num_sg > PVRDMA_MAX_FAST_REG_PAGES)
+ return ERR_PTR(-EINVAL);
+
+ mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+ if (!mr)
+ return ERR_PTR(-ENOMEM);
+
+ mr->pages = kzalloc(size, GFP_KERNEL);
+ if (!mr->pages) {
+ ret = -ENOMEM;
+ goto freemr;
+ }
+
+ ret = pvrdma_page_dir_init(dev, &mr->pdir, max_num_sg, false);
+ if (ret) {
+ dev_warn(&dev->pdev->dev,
+ "failed to allocate page dir for mr\n");
+ ret = -ENOMEM;
+ goto freepages;
+ }
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_MR;
+ cmd->pd_handle = to_vpd(pd)->pd_handle;
+ cmd->access_flags = 0;
+ cmd->flags = PVRDMA_MR_FLAG_FRMR;
+ cmd->nchunks = max_num_sg;
+
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_MR_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not create FR mem region, error: %d\n", ret);
+ goto freepdir;
+ }
+
+ mr->max_pages = max_num_sg;
+ mr->mmr.mr_handle = resp->mr_handle;
+ mr->ibmr.lkey = resp->lkey;
+ mr->ibmr.rkey = resp->rkey;
+ mr->page_shift = PAGE_SHIFT;
+ mr->umem = NULL;
+
+ return &mr->ibmr;
+
+freepdir:
+ pvrdma_page_dir_cleanup(dev, &mr->pdir);
+freepages:
+ kfree(mr->pages);
+freemr:
+ kfree(mr);
+ return ERR_PTR(ret);
+}
+
+/**
+ * pvrdma_dereg_mr - deregister a memory region
+ * @ibmr: memory region
+ *
+ * @return: 0 on success.
+ */
+int pvrdma_dereg_mr(struct ib_mr *ibmr)
+{
+ struct pvrdma_user_mr *mr = to_vmr(ibmr);
+ struct pvrdma_dev *dev = to_vdev(ibmr->device);
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_destroy_mr *cmd = &req.destroy_mr;
+ int ret;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_DESTROY_MR;
+ cmd->mr_handle = mr->mmr.mr_handle;
+ ret = pvrdma_cmd_post(dev, &req, NULL, 0);
+ if (ret < 0)
+ dev_warn(&dev->pdev->dev,
+ "could not deregister mem region, error: %d\n", ret);
+
+ pvrdma_page_dir_cleanup(dev, &mr->pdir);
+ if (mr->umem)
+ ib_umem_release(mr->umem);
+
+ kfree(mr->pages);
+ kfree(mr);
+
+ return 0;
+}
+
+static int pvrdma_set_page(struct ib_mr *ibmr, u64 addr)
+{
+ struct pvrdma_user_mr *mr = to_vmr(ibmr);
+
+ if (mr->npages == mr->max_pages)
+ return -ENOMEM;
+
+ mr->pages[mr->npages++] = addr;
+ return 0;
+}
+
+int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
+ unsigned int *sg_offset)
+{
+ struct pvrdma_user_mr *mr = to_vmr(ibmr);
+ struct pvrdma_dev *dev = to_vdev(ibmr->device);
+ int ret;
+
+ mr->npages = 0;
+
+ ret = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, pvrdma_set_page);
+ if (ret < 0)
+ dev_warn(&dev->pdev->dev, "could not map sg to pages\n");
+
+ return ret;
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
new file mode 100644
index 000000000000..c8c01e558125
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
@@ -0,0 +1,972 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "pvrdma.h"
+
+static inline void get_cqs(struct pvrdma_qp *qp, struct pvrdma_cq **send_cq,
+ struct pvrdma_cq **recv_cq)
+{
+ *send_cq = to_vcq(qp->ibqp.send_cq);
+ *recv_cq = to_vcq(qp->ibqp.recv_cq);
+}
+
+static void pvrdma_lock_cqs(struct pvrdma_cq *scq, struct pvrdma_cq *rcq,
+ unsigned long *scq_flags,
+ unsigned long *rcq_flags)
+ __acquires(scq->cq_lock) __acquires(rcq->cq_lock)
+{
+ if (scq == rcq) {
+ spin_lock_irqsave(&scq->cq_lock, *scq_flags);
+ __acquire(rcq->cq_lock);
+ } else if (scq->cq_handle < rcq->cq_handle) {
+ spin_lock_irqsave(&scq->cq_lock, *scq_flags);
+ spin_lock_irqsave_nested(&rcq->cq_lock, *rcq_flags,
+ SINGLE_DEPTH_NESTING);
+ } else {
+ spin_lock_irqsave(&rcq->cq_lock, *rcq_flags);
+ spin_lock_irqsave_nested(&scq->cq_lock, *scq_flags,
+ SINGLE_DEPTH_NESTING);
+ }
+}
+
+static void pvrdma_unlock_cqs(struct pvrdma_cq *scq, struct pvrdma_cq *rcq,
+ unsigned long *scq_flags,
+ unsigned long *rcq_flags)
+ __releases(scq->cq_lock) __releases(rcq->cq_lock)
+{
+ if (scq == rcq) {
+ __release(rcq->cq_lock);
+ spin_unlock_irqrestore(&scq->cq_lock, *scq_flags);
+ } else if (scq->cq_handle < rcq->cq_handle) {
+ spin_unlock_irqrestore(&rcq->cq_lock, *rcq_flags);
+ spin_unlock_irqrestore(&scq->cq_lock, *scq_flags);
+ } else {
+ spin_unlock_irqrestore(&scq->cq_lock, *scq_flags);
+ spin_unlock_irqrestore(&rcq->cq_lock, *rcq_flags);
+ }
+}
+
+static void pvrdma_reset_qp(struct pvrdma_qp *qp)
+{
+ struct pvrdma_cq *scq, *rcq;
+ unsigned long scq_flags, rcq_flags;
+
+ /* Clean up cqes */
+ get_cqs(qp, &scq, &rcq);
+ pvrdma_lock_cqs(scq, rcq, &scq_flags, &rcq_flags);
+
+ _pvrdma_flush_cqe(qp, scq);
+ if (scq != rcq)
+ _pvrdma_flush_cqe(qp, rcq);
+
+ pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags);
+
+ /*
+ * Reset queuepair. The checks are because usermode queuepairs won't
+ * have kernel ringstates.
+ */
+ if (qp->rq.ring) {
+ atomic_set(&qp->rq.ring->cons_head, 0);
+ atomic_set(&qp->rq.ring->prod_tail, 0);
+ }
+ if (qp->sq.ring) {
+ atomic_set(&qp->sq.ring->cons_head, 0);
+ atomic_set(&qp->sq.ring->prod_tail, 0);
+ }
+}
+
+static int pvrdma_set_rq_size(struct pvrdma_dev *dev,
+ struct ib_qp_cap *req_cap,
+ struct pvrdma_qp *qp)
+{
+ if (req_cap->max_recv_wr > dev->dsr->caps.max_qp_wr ||
+ req_cap->max_recv_sge > dev->dsr->caps.max_sge) {
+ dev_warn(&dev->pdev->dev, "recv queue size invalid\n");
+ return -EINVAL;
+ }
+
+ qp->rq.wqe_cnt = roundup_pow_of_two(max(1U, req_cap->max_recv_wr));
+ qp->rq.max_sg = roundup_pow_of_two(max(1U, req_cap->max_recv_sge));
+
+ /* Write back */
+ req_cap->max_recv_wr = qp->rq.wqe_cnt;
+ req_cap->max_recv_sge = qp->rq.max_sg;
+
+ qp->rq.wqe_size = roundup_pow_of_two(sizeof(struct pvrdma_rq_wqe_hdr) +
+ sizeof(struct pvrdma_sge) *
+ qp->rq.max_sg);
+ qp->npages_recv = (qp->rq.wqe_cnt * qp->rq.wqe_size + PAGE_SIZE - 1) /
+ PAGE_SIZE;
+
+ return 0;
+}
+
+static int pvrdma_set_sq_size(struct pvrdma_dev *dev, struct ib_qp_cap *req_cap,
+ enum ib_qp_type type, struct pvrdma_qp *qp)
+{
+ if (req_cap->max_send_wr > dev->dsr->caps.max_qp_wr ||
+ req_cap->max_send_sge > dev->dsr->caps.max_sge) {
+ dev_warn(&dev->pdev->dev, "send queue size invalid\n");
+ return -EINVAL;
+ }
+
+ qp->sq.wqe_cnt = roundup_pow_of_two(max(1U, req_cap->max_send_wr));
+ qp->sq.max_sg = roundup_pow_of_two(max(1U, req_cap->max_send_sge));
+
+ /* Write back */
+ req_cap->max_send_wr = qp->sq.wqe_cnt;
+ req_cap->max_send_sge = qp->sq.max_sg;
+
+ qp->sq.wqe_size = roundup_pow_of_two(sizeof(struct pvrdma_sq_wqe_hdr) +
+ sizeof(struct pvrdma_sge) *
+ qp->sq.max_sg);
+ /* Note: one extra page for the header. */
+ qp->npages_send = 1 + (qp->sq.wqe_cnt * qp->sq.wqe_size +
+ PAGE_SIZE - 1) / PAGE_SIZE;
+
+ return 0;
+}
+
+/**
+ * pvrdma_create_qp - create queue pair
+ * @pd: protection domain
+ * @init_attr: queue pair attributes
+ * @udata: user data
+ *
+ * @return: the ib_qp pointer on success, otherwise returns an errno.
+ */
+struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct pvrdma_qp *qp = NULL;
+ struct pvrdma_dev *dev = to_vdev(pd->device);
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_qp *cmd = &req.create_qp;
+ struct pvrdma_cmd_create_qp_resp *resp = &rsp.create_qp_resp;
+ struct pvrdma_create_qp ucmd;
+ unsigned long flags;
+ int ret;
+
+ if (init_attr->create_flags) {
+ dev_warn(&dev->pdev->dev,
+ "invalid create queuepair flags %#x\n",
+ init_attr->create_flags);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (init_attr->qp_type != IB_QPT_RC &&
+ init_attr->qp_type != IB_QPT_UD &&
+ init_attr->qp_type != IB_QPT_GSI) {
+ dev_warn(&dev->pdev->dev, "queuepair type %d not supported\n",
+ init_attr->qp_type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!atomic_add_unless(&dev->num_qps, 1, dev->dsr->caps.max_qp))
+ return ERR_PTR(-ENOMEM);
+
+ switch (init_attr->qp_type) {
+ case IB_QPT_GSI:
+ if (init_attr->port_num == 0 ||
+ init_attr->port_num > pd->device->phys_port_cnt ||
+ udata) {
+ dev_warn(&dev->pdev->dev, "invalid queuepair attrs\n");
+ ret = -EINVAL;
+ goto err_qp;
+ }
+ /* fall through */
+ case IB_QPT_RC:
+ case IB_QPT_UD:
+ qp = kzalloc(sizeof(*qp), GFP_KERNEL);
+ if (!qp) {
+ ret = -ENOMEM;
+ goto err_qp;
+ }
+
+ spin_lock_init(&qp->sq.lock);
+ spin_lock_init(&qp->rq.lock);
+ mutex_init(&qp->mutex);
+ atomic_set(&qp->refcnt, 1);
+ init_waitqueue_head(&qp->wait);
+
+ qp->state = IB_QPS_RESET;
+
+ if (pd->uobject && udata) {
+ dev_dbg(&dev->pdev->dev,
+ "create queuepair from user space\n");
+
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
+ ret = -EFAULT;
+ goto err_qp;
+ }
+
+ /* set qp->sq.wqe_cnt, shift, buf_size.. */
+ qp->rumem = ib_umem_get(pd->uobject->context,
+ ucmd.rbuf_addr,
+ ucmd.rbuf_size, 0, 0);
+ if (IS_ERR(qp->rumem)) {
+ ret = PTR_ERR(qp->rumem);
+ goto err_qp;
+ }
+
+ qp->sumem = ib_umem_get(pd->uobject->context,
+ ucmd.sbuf_addr,
+ ucmd.sbuf_size, 0, 0);
+ if (IS_ERR(qp->sumem)) {
+ ib_umem_release(qp->rumem);
+ ret = PTR_ERR(qp->sumem);
+ goto err_qp;
+ }
+
+ qp->npages_send = ib_umem_page_count(qp->sumem);
+ qp->npages_recv = ib_umem_page_count(qp->rumem);
+ qp->npages = qp->npages_send + qp->npages_recv;
+ } else {
+ qp->is_kernel = true;
+
+ ret = pvrdma_set_sq_size(to_vdev(pd->device),
+ &init_attr->cap,
+ init_attr->qp_type, qp);
+ if (ret)
+ goto err_qp;
+
+ ret = pvrdma_set_rq_size(to_vdev(pd->device),
+ &init_attr->cap, qp);
+ if (ret)
+ goto err_qp;
+
+ qp->npages = qp->npages_send + qp->npages_recv;
+
+ /* Skip header page. */
+ qp->sq.offset = PAGE_SIZE;
+
+ /* Recv queue pages are after send pages. */
+ qp->rq.offset = qp->npages_send * PAGE_SIZE;
+ }
+
+ if (qp->npages < 0 || qp->npages > PVRDMA_PAGE_DIR_MAX_PAGES) {
+ dev_warn(&dev->pdev->dev,
+ "overflow pages in queuepair\n");
+ ret = -EINVAL;
+ goto err_umem;
+ }
+
+ ret = pvrdma_page_dir_init(dev, &qp->pdir, qp->npages,
+ qp->is_kernel);
+ if (ret) {
+ dev_warn(&dev->pdev->dev,
+ "could not allocate page directory\n");
+ goto err_umem;
+ }
+
+ if (!qp->is_kernel) {
+ pvrdma_page_dir_insert_umem(&qp->pdir, qp->sumem, 0);
+ pvrdma_page_dir_insert_umem(&qp->pdir, qp->rumem,
+ qp->npages_send);
+ } else {
+ /* Ring state is always the first page. */
+ qp->sq.ring = qp->pdir.pages[0];
+ qp->rq.ring = &qp->sq.ring[1];
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ goto err_qp;
+ }
+
+ /* Not supported */
+ init_attr->cap.max_inline_data = 0;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_QP;
+ cmd->pd_handle = to_vpd(pd)->pd_handle;
+ cmd->send_cq_handle = to_vcq(init_attr->send_cq)->cq_handle;
+ cmd->recv_cq_handle = to_vcq(init_attr->recv_cq)->cq_handle;
+ cmd->max_send_wr = init_attr->cap.max_send_wr;
+ cmd->max_recv_wr = init_attr->cap.max_recv_wr;
+ cmd->max_send_sge = init_attr->cap.max_send_sge;
+ cmd->max_recv_sge = init_attr->cap.max_recv_sge;
+ cmd->max_inline_data = init_attr->cap.max_inline_data;
+ cmd->sq_sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? 1 : 0;
+ cmd->qp_type = ib_qp_type_to_pvrdma(init_attr->qp_type);
+ cmd->access_flags = IB_ACCESS_LOCAL_WRITE;
+ cmd->total_chunks = qp->npages;
+ cmd->send_chunks = qp->npages_send - 1;
+ cmd->pdir_dma = qp->pdir.dir_dma;
+
+ dev_dbg(&dev->pdev->dev, "create queuepair with %d, %d, %d, %d\n",
+ cmd->max_send_wr, cmd->max_recv_wr, cmd->max_send_sge,
+ cmd->max_recv_sge);
+
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_QP_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not create queuepair, error: %d\n", ret);
+ goto err_pdir;
+ }
+
+ /* max_send_wr/_recv_wr/_send_sge/_recv_sge/_inline_data */
+ qp->qp_handle = resp->qpn;
+ qp->port = init_attr->port_num;
+ qp->ibqp.qp_num = resp->qpn;
+ spin_lock_irqsave(&dev->qp_tbl_lock, flags);
+ dev->qp_tbl[qp->qp_handle % dev->dsr->caps.max_qp] = qp;
+ spin_unlock_irqrestore(&dev->qp_tbl_lock, flags);
+
+ return &qp->ibqp;
+
+err_pdir:
+ pvrdma_page_dir_cleanup(dev, &qp->pdir);
+err_umem:
+ if (pd->uobject && udata) {
+ if (qp->rumem)
+ ib_umem_release(qp->rumem);
+ if (qp->sumem)
+ ib_umem_release(qp->sumem);
+ }
+err_qp:
+ kfree(qp);
+ atomic_dec(&dev->num_qps);
+
+ return ERR_PTR(ret);
+}
+
+static void pvrdma_free_qp(struct pvrdma_qp *qp)
+{
+ struct pvrdma_dev *dev = to_vdev(qp->ibqp.device);
+ struct pvrdma_cq *scq;
+ struct pvrdma_cq *rcq;
+ unsigned long flags, scq_flags, rcq_flags;
+
+ /* In case cq is polling */
+ get_cqs(qp, &scq, &rcq);
+ pvrdma_lock_cqs(scq, rcq, &scq_flags, &rcq_flags);
+
+ _pvrdma_flush_cqe(qp, scq);
+ if (scq != rcq)
+ _pvrdma_flush_cqe(qp, rcq);
+
+ spin_lock_irqsave(&dev->qp_tbl_lock, flags);
+ dev->qp_tbl[qp->qp_handle] = NULL;
+ spin_unlock_irqrestore(&dev->qp_tbl_lock, flags);
+
+ pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags);
+
+ atomic_dec(&qp->refcnt);
+ wait_event(qp->wait, !atomic_read(&qp->refcnt));
+
+ pvrdma_page_dir_cleanup(dev, &qp->pdir);
+
+ kfree(qp);
+
+ atomic_dec(&dev->num_qps);
+}
+
+/**
+ * pvrdma_destroy_qp - destroy a queue pair
+ * @qp: the queue pair to destroy
+ *
+ * @return: 0 on success.
+ */
+int pvrdma_destroy_qp(struct ib_qp *qp)
+{
+ struct pvrdma_qp *vqp = to_vqp(qp);
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_destroy_qp *cmd = &req.destroy_qp;
+ int ret;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_DESTROY_QP;
+ cmd->qp_handle = vqp->qp_handle;
+
+ ret = pvrdma_cmd_post(to_vdev(qp->device), &req, NULL, 0);
+ if (ret < 0)
+ dev_warn(&to_vdev(qp->device)->pdev->dev,
+ "destroy queuepair failed, error: %d\n", ret);
+
+ pvrdma_free_qp(vqp);
+
+ return 0;
+}
+
+/**
+ * pvrdma_modify_qp - modify queue pair attributes
+ * @ibqp: the queue pair
+ * @attr: the new queue pair's attributes
+ * @attr_mask: attributes mask
+ * @udata: user data
+ *
+ * @returns 0 on success, otherwise returns an errno.
+ */
+int pvrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+{
+ struct pvrdma_dev *dev = to_vdev(ibqp->device);
+ struct pvrdma_qp *qp = to_vqp(ibqp);
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_modify_qp *cmd = &req.modify_qp;
+ int cur_state, next_state;
+ int ret;
+
+ /* Sanity checking. Should need lock here */
+ mutex_lock(&qp->mutex);
+ cur_state = (attr_mask & IB_QP_CUR_STATE) ? attr->cur_qp_state :
+ qp->state;
+ next_state = (attr_mask & IB_QP_STATE) ? attr->qp_state : cur_state;
+
+ if (!ib_modify_qp_is_ok(cur_state, next_state, ibqp->qp_type,
+ attr_mask, IB_LINK_LAYER_ETHERNET)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (attr_mask & IB_QP_PORT) {
+ if (attr->port_num == 0 ||
+ attr->port_num > ibqp->device->phys_port_cnt) {
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ if (attr_mask & IB_QP_MIN_RNR_TIMER) {
+ if (attr->min_rnr_timer > 31) {
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ if (attr_mask & IB_QP_PKEY_INDEX) {
+ if (attr->pkey_index >= dev->dsr->caps.max_pkeys) {
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ if (attr_mask & IB_QP_QKEY)
+ qp->qkey = attr->qkey;
+
+ if (cur_state == next_state && cur_state == IB_QPS_RESET) {
+ ret = 0;
+ goto out;
+ }
+
+ qp->state = next_state;
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_MODIFY_QP;
+ cmd->qp_handle = qp->qp_handle;
+ cmd->attr_mask = ib_qp_attr_mask_to_pvrdma(attr_mask);
+ cmd->attrs.qp_state = ib_qp_state_to_pvrdma(attr->qp_state);
+ cmd->attrs.cur_qp_state =
+ ib_qp_state_to_pvrdma(attr->cur_qp_state);
+ cmd->attrs.path_mtu = ib_mtu_to_pvrdma(attr->path_mtu);
+ cmd->attrs.path_mig_state =
+ ib_mig_state_to_pvrdma(attr->path_mig_state);
+ cmd->attrs.qkey = attr->qkey;
+ cmd->attrs.rq_psn = attr->rq_psn;
+ cmd->attrs.sq_psn = attr->sq_psn;
+ cmd->attrs.dest_qp_num = attr->dest_qp_num;
+ cmd->attrs.qp_access_flags =
+ ib_access_flags_to_pvrdma(attr->qp_access_flags);
+ cmd->attrs.pkey_index = attr->pkey_index;
+ cmd->attrs.alt_pkey_index = attr->alt_pkey_index;
+ cmd->attrs.en_sqd_async_notify = attr->en_sqd_async_notify;
+ cmd->attrs.sq_draining = attr->sq_draining;
+ cmd->attrs.max_rd_atomic = attr->max_rd_atomic;
+ cmd->attrs.max_dest_rd_atomic = attr->max_dest_rd_atomic;
+ cmd->attrs.min_rnr_timer = attr->min_rnr_timer;
+ cmd->attrs.port_num = attr->port_num;
+ cmd->attrs.timeout = attr->timeout;
+ cmd->attrs.retry_cnt = attr->retry_cnt;
+ cmd->attrs.rnr_retry = attr->rnr_retry;
+ cmd->attrs.alt_port_num = attr->alt_port_num;
+ cmd->attrs.alt_timeout = attr->alt_timeout;
+ ib_qp_cap_to_pvrdma(&cmd->attrs.cap, &attr->cap);
+ ib_ah_attr_to_pvrdma(&cmd->attrs.ah_attr, &attr->ah_attr);
+ ib_ah_attr_to_pvrdma(&cmd->attrs.alt_ah_attr, &attr->alt_ah_attr);
+
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_MODIFY_QP_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not modify queuepair, error: %d\n", ret);
+ } else if (rsp.hdr.err > 0) {
+ dev_warn(&dev->pdev->dev,
+ "cannot modify queuepair, error: %d\n", rsp.hdr.err);
+ ret = -EINVAL;
+ }
+
+ if (ret == 0 && next_state == IB_QPS_RESET)
+ pvrdma_reset_qp(qp);
+
+out:
+ mutex_unlock(&qp->mutex);
+
+ return ret;
+}
+
+static inline void *get_sq_wqe(struct pvrdma_qp *qp, int n)
+{
+ return pvrdma_page_dir_get_ptr(&qp->pdir,
+ qp->sq.offset + n * qp->sq.wqe_size);
+}
+
+static inline void *get_rq_wqe(struct pvrdma_qp *qp, int n)
+{
+ return pvrdma_page_dir_get_ptr(&qp->pdir,
+ qp->rq.offset + n * qp->rq.wqe_size);
+}
+
+static int set_reg_seg(struct pvrdma_sq_wqe_hdr *wqe_hdr, struct ib_reg_wr *wr)
+{
+ struct pvrdma_user_mr *mr = to_vmr(wr->mr);
+
+ wqe_hdr->wr.fast_reg.iova_start = mr->ibmr.iova;
+ wqe_hdr->wr.fast_reg.pl_pdir_dma = mr->pdir.dir_dma;
+ wqe_hdr->wr.fast_reg.page_shift = mr->page_shift;
+ wqe_hdr->wr.fast_reg.page_list_len = mr->npages;
+ wqe_hdr->wr.fast_reg.length = mr->ibmr.length;
+ wqe_hdr->wr.fast_reg.access_flags = wr->access;
+ wqe_hdr->wr.fast_reg.rkey = wr->key;
+
+ return pvrdma_page_dir_insert_page_list(&mr->pdir, mr->pages,
+ mr->npages);
+}
+
+/**
+ * pvrdma_post_send - post send work request entries on a QP
+ * @ibqp: the QP
+ * @wr: work request list to post
+ * @bad_wr: the first bad WR returned
+ *
+ * @return: 0 on success, otherwise errno returned.
+ */
+int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr)
+{
+ struct pvrdma_qp *qp = to_vqp(ibqp);
+ struct pvrdma_dev *dev = to_vdev(ibqp->device);
+ unsigned long flags;
+ struct pvrdma_sq_wqe_hdr *wqe_hdr;
+ struct pvrdma_sge *sge;
+ int i, index;
+ int nreq;
+ int ret;
+
+ /*
+ * In states lower than RTS, we can fail immediately. In other states,
+ * just post and let the device figure it out.
+ */
+ if (qp->state < IB_QPS_RTS) {
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&qp->sq.lock, flags);
+
+ index = pvrdma_idx(&qp->sq.ring->prod_tail, qp->sq.wqe_cnt);
+ for (nreq = 0; wr; nreq++, wr = wr->next) {
+ unsigned int tail;
+
+ if (unlikely(!pvrdma_idx_ring_has_space(
+ qp->sq.ring, qp->sq.wqe_cnt, &tail))) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "send queue is full\n");
+ *bad_wr = wr;
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (unlikely(wr->num_sge > qp->sq.max_sg || wr->num_sge < 0)) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "send SGE overflow\n");
+ *bad_wr = wr;
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (unlikely(wr->opcode < 0)) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "invalid send opcode\n");
+ *bad_wr = wr;
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Only support UD, RC.
+ * Need to check opcode table for thorough checking.
+ * opcode _UD _UC _RC
+ * _SEND x x x
+ * _SEND_WITH_IMM x x x
+ * _RDMA_WRITE x x
+ * _RDMA_WRITE_WITH_IMM x x
+ * _LOCAL_INV x x
+ * _SEND_WITH_INV x x
+ * _RDMA_READ x
+ * _ATOMIC_CMP_AND_SWP x
+ * _ATOMIC_FETCH_AND_ADD x
+ * _MASK_ATOMIC_CMP_AND_SWP x
+ * _MASK_ATOMIC_FETCH_AND_ADD x
+ * _REG_MR x
+ *
+ */
+ if (qp->ibqp.qp_type != IB_QPT_UD &&
+ qp->ibqp.qp_type != IB_QPT_RC &&
+ wr->opcode != IB_WR_SEND) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "unsupported queuepair type\n");
+ *bad_wr = wr;
+ ret = -EINVAL;
+ goto out;
+ } else if (qp->ibqp.qp_type == IB_QPT_UD ||
+ qp->ibqp.qp_type == IB_QPT_GSI) {
+ if (wr->opcode != IB_WR_SEND &&
+ wr->opcode != IB_WR_SEND_WITH_IMM) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "invalid send opcode\n");
+ *bad_wr = wr;
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ wqe_hdr = (struct pvrdma_sq_wqe_hdr *)get_sq_wqe(qp, index);
+ memset(wqe_hdr, 0, sizeof(*wqe_hdr));
+ wqe_hdr->wr_id = wr->wr_id;
+ wqe_hdr->num_sge = wr->num_sge;
+ wqe_hdr->opcode = ib_wr_opcode_to_pvrdma(wr->opcode);
+ wqe_hdr->send_flags = ib_send_flags_to_pvrdma(wr->send_flags);
+ if (wr->opcode == IB_WR_SEND_WITH_IMM ||
+ wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
+ wqe_hdr->ex.imm_data = wr->ex.imm_data;
+
+ switch (qp->ibqp.qp_type) {
+ case IB_QPT_GSI:
+ case IB_QPT_UD:
+ if (unlikely(!ud_wr(wr)->ah)) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "invalid address handle\n");
+ *bad_wr = wr;
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Use qkey from qp context if high order bit set,
+ * otherwise from work request.
+ */
+ wqe_hdr->wr.ud.remote_qpn = ud_wr(wr)->remote_qpn;
+ wqe_hdr->wr.ud.remote_qkey =
+ ud_wr(wr)->remote_qkey & 0x80000000 ?
+ qp->qkey : ud_wr(wr)->remote_qkey;
+ wqe_hdr->wr.ud.av = to_vah(ud_wr(wr)->ah)->av;
+
+ break;
+ case IB_QPT_RC:
+ switch (wr->opcode) {
+ case IB_WR_RDMA_READ:
+ case IB_WR_RDMA_WRITE:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ wqe_hdr->wr.rdma.remote_addr =
+ rdma_wr(wr)->remote_addr;
+ wqe_hdr->wr.rdma.rkey = rdma_wr(wr)->rkey;
+ break;
+ case IB_WR_LOCAL_INV:
+ case IB_WR_SEND_WITH_INV:
+ wqe_hdr->ex.invalidate_rkey =
+ wr->ex.invalidate_rkey;
+ break;
+ case IB_WR_ATOMIC_CMP_AND_SWP:
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ wqe_hdr->wr.atomic.remote_addr =
+ atomic_wr(wr)->remote_addr;
+ wqe_hdr->wr.atomic.rkey = atomic_wr(wr)->rkey;
+ wqe_hdr->wr.atomic.compare_add =
+ atomic_wr(wr)->compare_add;
+ if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP)
+ wqe_hdr->wr.atomic.swap =
+ atomic_wr(wr)->swap;
+ break;
+ case IB_WR_REG_MR:
+ ret = set_reg_seg(wqe_hdr, reg_wr(wr));
+ if (ret < 0) {
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "Failed to set fast register work request\n");
+ *bad_wr = wr;
+ goto out;
+ }
+ break;
+ default:
+ break;
+ }
+
+ break;
+ default:
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "invalid queuepair type\n");
+ ret = -EINVAL;
+ *bad_wr = wr;
+ goto out;
+ }
+
+ sge = (struct pvrdma_sge *)(wqe_hdr + 1);
+ for (i = 0; i < wr->num_sge; i++) {
+ /* Need to check wqe_size 0 or max size */
+ sge->addr = wr->sg_list[i].addr;
+ sge->length = wr->sg_list[i].length;
+ sge->lkey = wr->sg_list[i].lkey;
+ sge++;
+ }
+
+ /* Make sure wqe is written before index update */
+ smp_wmb();
+
+ index++;
+ if (unlikely(index >= qp->sq.wqe_cnt))
+ index = 0;
+ /* Update shared sq ring */
+ pvrdma_idx_ring_inc(&qp->sq.ring->prod_tail,
+ qp->sq.wqe_cnt);
+ }
+
+ ret = 0;
+
+out:
+ spin_unlock_irqrestore(&qp->sq.lock, flags);
+
+ if (!ret)
+ pvrdma_write_uar_qp(dev, PVRDMA_UAR_QP_SEND | qp->qp_handle);
+
+ return ret;
+}
+
+/**
+ * pvrdma_post_receive - post receive work request entries on a QP
+ * @ibqp: the QP
+ * @wr: the work request list to post
+ * @bad_wr: the first bad WR returned
+ *
+ * @return: 0 on success, otherwise errno returned.
+ */
+int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
+{
+ struct pvrdma_dev *dev = to_vdev(ibqp->device);
+ unsigned long flags;
+ struct pvrdma_qp *qp = to_vqp(ibqp);
+ struct pvrdma_rq_wqe_hdr *wqe_hdr;
+ struct pvrdma_sge *sge;
+ int index, nreq;
+ int ret = 0;
+ int i;
+
+ /*
+ * In the RESET state, we can fail immediately. For other states,
+ * just post and let the device figure it out.
+ */
+ if (qp->state == IB_QPS_RESET) {
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&qp->rq.lock, flags);
+
+ index = pvrdma_idx(&qp->rq.ring->prod_tail, qp->rq.wqe_cnt);
+ for (nreq = 0; wr; nreq++, wr = wr->next) {
+ unsigned int tail;
+
+ if (unlikely(wr->num_sge > qp->rq.max_sg ||
+ wr->num_sge < 0)) {
+ ret = -EINVAL;
+ *bad_wr = wr;
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "recv SGE overflow\n");
+ goto out;
+ }
+
+ if (unlikely(!pvrdma_idx_ring_has_space(
+ qp->rq.ring, qp->rq.wqe_cnt, &tail))) {
+ ret = -ENOMEM;
+ *bad_wr = wr;
+ dev_warn_ratelimited(&dev->pdev->dev,
+ "recv queue full\n");
+ goto out;
+ }
+
+ wqe_hdr = (struct pvrdma_rq_wqe_hdr *)get_rq_wqe(qp, index);
+ wqe_hdr->wr_id = wr->wr_id;
+ wqe_hdr->num_sge = wr->num_sge;
+ wqe_hdr->total_len = 0;
+
+ sge = (struct pvrdma_sge *)(wqe_hdr + 1);
+ for (i = 0; i < wr->num_sge; i++) {
+ sge->addr = wr->sg_list[i].addr;
+ sge->length = wr->sg_list[i].length;
+ sge->lkey = wr->sg_list[i].lkey;
+ sge++;
+ }
+
+ /* Make sure wqe is written before index update */
+ smp_wmb();
+
+ index++;
+ if (unlikely(index >= qp->rq.wqe_cnt))
+ index = 0;
+ /* Update shared rq ring */
+ pvrdma_idx_ring_inc(&qp->rq.ring->prod_tail,
+ qp->rq.wqe_cnt);
+ }
+
+ spin_unlock_irqrestore(&qp->rq.lock, flags);
+
+ pvrdma_write_uar_qp(dev, PVRDMA_UAR_QP_RECV | qp->qp_handle);
+
+ return ret;
+
+out:
+ spin_unlock_irqrestore(&qp->rq.lock, flags);
+
+ return ret;
+}
+
+/**
+ * pvrdma_query_qp - query a queue pair's attributes
+ * @ibqp: the queue pair to query
+ * @attr: the queue pair's attributes
+ * @attr_mask: attributes mask
+ * @init_attr: initial queue pair attributes
+ *
+ * @returns 0 on success, otherwise returns an errno.
+ */
+int pvrdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_qp_init_attr *init_attr)
+{
+ struct pvrdma_dev *dev = to_vdev(ibqp->device);
+ struct pvrdma_qp *qp = to_vqp(ibqp);
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_query_qp *cmd = &req.query_qp;
+ struct pvrdma_cmd_query_qp_resp *resp = &rsp.query_qp_resp;
+ int ret = 0;
+
+ mutex_lock(&qp->mutex);
+
+ if (qp->state == IB_QPS_RESET) {
+ attr->qp_state = IB_QPS_RESET;
+ goto out;
+ }
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_QUERY_QP;
+ cmd->qp_handle = qp->qp_handle;
+ cmd->attr_mask = ib_qp_attr_mask_to_pvrdma(attr_mask);
+
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_QUERY_QP_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not query queuepair, error: %d\n", ret);
+ goto out;
+ }
+
+ attr->qp_state = pvrdma_qp_state_to_ib(resp->attrs.qp_state);
+ attr->cur_qp_state =
+ pvrdma_qp_state_to_ib(resp->attrs.cur_qp_state);
+ attr->path_mtu = pvrdma_mtu_to_ib(resp->attrs.path_mtu);
+ attr->path_mig_state =
+ pvrdma_mig_state_to_ib(resp->attrs.path_mig_state);
+ attr->qkey = resp->attrs.qkey;
+ attr->rq_psn = resp->attrs.rq_psn;
+ attr->sq_psn = resp->attrs.sq_psn;
+ attr->dest_qp_num = resp->attrs.dest_qp_num;
+ attr->qp_access_flags =
+ pvrdma_access_flags_to_ib(resp->attrs.qp_access_flags);
+ attr->pkey_index = resp->attrs.pkey_index;
+ attr->alt_pkey_index = resp->attrs.alt_pkey_index;
+ attr->en_sqd_async_notify = resp->attrs.en_sqd_async_notify;
+ attr->sq_draining = resp->attrs.sq_draining;
+ attr->max_rd_atomic = resp->attrs.max_rd_atomic;
+ attr->max_dest_rd_atomic = resp->attrs.max_dest_rd_atomic;
+ attr->min_rnr_timer = resp->attrs.min_rnr_timer;
+ attr->port_num = resp->attrs.port_num;
+ attr->timeout = resp->attrs.timeout;
+ attr->retry_cnt = resp->attrs.retry_cnt;
+ attr->rnr_retry = resp->attrs.rnr_retry;
+ attr->alt_port_num = resp->attrs.alt_port_num;
+ attr->alt_timeout = resp->attrs.alt_timeout;
+ pvrdma_qp_cap_to_ib(&attr->cap, &resp->attrs.cap);
+ pvrdma_ah_attr_to_ib(&attr->ah_attr, &resp->attrs.ah_attr);
+ pvrdma_ah_attr_to_ib(&attr->alt_ah_attr, &resp->attrs.alt_ah_attr);
+
+ qp->state = attr->qp_state;
+
+ ret = 0;
+
+out:
+ attr->cur_qp_state = attr->qp_state;
+
+ init_attr->event_handler = qp->ibqp.event_handler;
+ init_attr->qp_context = qp->ibqp.qp_context;
+ init_attr->send_cq = qp->ibqp.send_cq;
+ init_attr->recv_cq = qp->ibqp.recv_cq;
+ init_attr->srq = qp->ibqp.srq;
+ init_attr->xrcd = NULL;
+ init_attr->cap = attr->cap;
+ init_attr->sq_sig_type = 0;
+ init_attr->qp_type = qp->ibqp.qp_type;
+ init_attr->create_flags = 0;
+ init_attr->port_num = qp->port;
+
+ mutex_unlock(&qp->mutex);
+ return ret;
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
new file mode 100644
index 000000000000..ed9022a91a1d
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PVRDMA_RING_H__
+#define __PVRDMA_RING_H__
+
+#include <linux/types.h>
+
+#define PVRDMA_INVALID_IDX -1 /* Invalid index. */
+
+struct pvrdma_ring {
+ atomic_t prod_tail; /* Producer tail. */
+ atomic_t cons_head; /* Consumer head. */
+};
+
+struct pvrdma_ring_state {
+ struct pvrdma_ring tx; /* Tx ring. */
+ struct pvrdma_ring rx; /* Rx ring. */
+};
+
+static inline int pvrdma_idx_valid(__u32 idx, __u32 max_elems)
+{
+ /* Generates fewer instructions than a less-than. */
+ return (idx & ~((max_elems << 1) - 1)) == 0;
+}
+
+static inline __s32 pvrdma_idx(atomic_t *var, __u32 max_elems)
+{
+ const unsigned int idx = atomic_read(var);
+
+ if (pvrdma_idx_valid(idx, max_elems))
+ return idx & (max_elems - 1);
+ return PVRDMA_INVALID_IDX;
+}
+
+static inline void pvrdma_idx_ring_inc(atomic_t *var, __u32 max_elems)
+{
+ __u32 idx = atomic_read(var) + 1; /* Increment. */
+
+ idx &= (max_elems << 1) - 1; /* Modulo size, flip gen. */
+ atomic_set(var, idx);
+}
+
+static inline __s32 pvrdma_idx_ring_has_space(const struct pvrdma_ring *r,
+ __u32 max_elems, __u32 *out_tail)
+{
+ const __u32 tail = atomic_read(&r->prod_tail);
+ const __u32 head = atomic_read(&r->cons_head);
+
+ if (pvrdma_idx_valid(tail, max_elems) &&
+ pvrdma_idx_valid(head, max_elems)) {
+ *out_tail = tail & (max_elems - 1);
+ return tail != (head ^ max_elems);
+ }
+ return PVRDMA_INVALID_IDX;
+}
+
+static inline __s32 pvrdma_idx_ring_has_data(const struct pvrdma_ring *r,
+ __u32 max_elems, __u32 *out_head)
+{
+ const __u32 tail = atomic_read(&r->prod_tail);
+ const __u32 head = atomic_read(&r->cons_head);
+
+ if (pvrdma_idx_valid(tail, max_elems) &&
+ pvrdma_idx_valid(head, max_elems)) {
+ *out_head = head & (max_elems - 1);
+ return tail != head;
+ }
+ return PVRDMA_INVALID_IDX;
+}
+
+static inline bool pvrdma_idx_ring_is_valid_idx(const struct pvrdma_ring *r,
+ __u32 max_elems, __u32 *idx)
+{
+ const __u32 tail = atomic_read(&r->prod_tail);
+ const __u32 head = atomic_read(&r->cons_head);
+
+ if (pvrdma_idx_valid(tail, max_elems) &&
+ pvrdma_idx_valid(head, max_elems) &&
+ pvrdma_idx_valid(*idx, max_elems)) {
+ if (tail > head && (*idx < tail && *idx >= head))
+ return true;
+ else if (head > tail && (*idx >= head || *idx < tail))
+ return true;
+ }
+ return false;
+}
+
+#endif /* __PVRDMA_RING_H__ */
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
new file mode 100644
index 000000000000..54891370d18a
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm/page.h>
+#include <linux/inet.h>
+#include <linux/io.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/vmw_pvrdma-abi.h>
+
+#include "pvrdma.h"
+
+/**
+ * pvrdma_query_device - query device
+ * @ibdev: the device to query
+ * @props: the device properties
+ * @uhw: user data
+ *
+ * @return: 0 on success, otherwise negative errno
+ */
+int pvrdma_query_device(struct ib_device *ibdev,
+ struct ib_device_attr *props,
+ struct ib_udata *uhw)
+{
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+
+ if (uhw->inlen || uhw->outlen)
+ return -EINVAL;
+
+ memset(props, 0, sizeof(*props));
+
+ props->fw_ver = dev->dsr->caps.fw_ver;
+ props->sys_image_guid = dev->dsr->caps.sys_image_guid;
+ props->max_mr_size = dev->dsr->caps.max_mr_size;
+ props->page_size_cap = dev->dsr->caps.page_size_cap;
+ props->vendor_id = dev->dsr->caps.vendor_id;
+ props->vendor_part_id = dev->pdev->device;
+ props->hw_ver = dev->dsr->caps.hw_ver;
+ props->max_qp = dev->dsr->caps.max_qp;
+ props->max_qp_wr = dev->dsr->caps.max_qp_wr;
+ props->device_cap_flags = dev->dsr->caps.device_cap_flags;
+ props->max_sge = dev->dsr->caps.max_sge;
+ props->max_cq = dev->dsr->caps.max_cq;
+ props->max_cqe = dev->dsr->caps.max_cqe;
+ props->max_mr = dev->dsr->caps.max_mr;
+ props->max_pd = dev->dsr->caps.max_pd;
+ props->max_qp_rd_atom = dev->dsr->caps.max_qp_rd_atom;
+ props->max_qp_init_rd_atom = dev->dsr->caps.max_qp_init_rd_atom;
+ props->atomic_cap =
+ dev->dsr->caps.atomic_ops &
+ (PVRDMA_ATOMIC_OP_COMP_SWAP | PVRDMA_ATOMIC_OP_FETCH_ADD) ?
+ IB_ATOMIC_HCA : IB_ATOMIC_NONE;
+ props->masked_atomic_cap = props->atomic_cap;
+ props->max_ah = dev->dsr->caps.max_ah;
+ props->max_pkeys = dev->dsr->caps.max_pkeys;
+ props->local_ca_ack_delay = dev->dsr->caps.local_ca_ack_delay;
+ if ((dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_LOCAL_INV) &&
+ (dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_REMOTE_INV) &&
+ (dev->dsr->caps.bmme_flags & PVRDMA_BMME_FLAG_FAST_REG_WR)) {
+ props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
+ }
+
+ return 0;
+}
+
+/**
+ * pvrdma_query_port - query device port attributes
+ * @ibdev: the device to query
+ * @port: the port number
+ * @props: the device properties
+ *
+ * @return: 0 on success, otherwise negative errno
+ */
+int pvrdma_query_port(struct ib_device *ibdev, u8 port,
+ struct ib_port_attr *props)
+{
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_query_port *cmd = &req.query_port;
+ struct pvrdma_cmd_query_port_resp *resp = &rsp.query_port_resp;
+ int err;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_QUERY_PORT;
+ cmd->port_num = port;
+
+ err = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_QUERY_PORT_RESP);
+ if (err < 0) {
+ dev_warn(&dev->pdev->dev,
+ "could not query port, error: %d\n", err);
+ return err;
+ }
+
+ memset(props, 0, sizeof(*props));
+
+ props->state = pvrdma_port_state_to_ib(resp->attrs.state);
+ props->max_mtu = pvrdma_mtu_to_ib(resp->attrs.max_mtu);
+ props->active_mtu = pvrdma_mtu_to_ib(resp->attrs.active_mtu);
+ props->gid_tbl_len = resp->attrs.gid_tbl_len;
+ props->port_cap_flags =
+ pvrdma_port_cap_flags_to_ib(resp->attrs.port_cap_flags);
+ props->max_msg_sz = resp->attrs.max_msg_sz;
+ props->bad_pkey_cntr = resp->attrs.bad_pkey_cntr;
+ props->qkey_viol_cntr = resp->attrs.qkey_viol_cntr;
+ props->pkey_tbl_len = resp->attrs.pkey_tbl_len;
+ props->lid = resp->attrs.lid;
+ props->sm_lid = resp->attrs.sm_lid;
+ props->lmc = resp->attrs.lmc;
+ props->max_vl_num = resp->attrs.max_vl_num;
+ props->sm_sl = resp->attrs.sm_sl;
+ props->subnet_timeout = resp->attrs.subnet_timeout;
+ props->init_type_reply = resp->attrs.init_type_reply;
+ props->active_width = pvrdma_port_width_to_ib(resp->attrs.active_width);
+ props->active_speed = pvrdma_port_speed_to_ib(resp->attrs.active_speed);
+ props->phys_state = resp->attrs.phys_state;
+
+ return 0;
+}
+
+/**
+ * pvrdma_query_gid - query device gid
+ * @ibdev: the device to query
+ * @port: the port number
+ * @index: the index
+ * @gid: the device gid value
+ *
+ * @return: 0 on success, otherwise negative errno
+ */
+int pvrdma_query_gid(struct ib_device *ibdev, u8 port, int index,
+ union ib_gid *gid)
+{
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+
+ if (index >= dev->dsr->caps.gid_tbl_len)
+ return -EINVAL;
+
+ memcpy(gid, &dev->sgid_tbl[index], sizeof(union ib_gid));
+
+ return 0;
+}
+
+/**
+ * pvrdma_query_pkey - query device port's P_Key table
+ * @ibdev: the device to query
+ * @port: the port number
+ * @index: the index
+ * @pkey: the device P_Key value
+ *
+ * @return: 0 on success, otherwise negative errno
+ */
+int pvrdma_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
+ u16 *pkey)
+{
+ int err = 0;
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_query_pkey *cmd = &req.query_pkey;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_QUERY_PKEY;
+ cmd->port_num = port;
+ cmd->index = index;
+
+ err = pvrdma_cmd_post(to_vdev(ibdev), &req, &rsp,
+ PVRDMA_CMD_QUERY_PKEY_RESP);
+ if (err < 0) {
+ dev_warn(&to_vdev(ibdev)->pdev->dev,
+ "could not query pkey, error: %d\n", err);
+ return err;
+ }
+
+ *pkey = rsp.query_pkey_resp.pkey;
+
+ return 0;
+}
+
+enum rdma_link_layer pvrdma_port_link_layer(struct ib_device *ibdev,
+ u8 port)
+{
+ return IB_LINK_LAYER_ETHERNET;
+}
+
+int pvrdma_modify_device(struct ib_device *ibdev, int mask,
+ struct ib_device_modify *props)
+{
+ unsigned long flags;
+
+ if (mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID |
+ IB_DEVICE_MODIFY_NODE_DESC)) {
+ dev_warn(&to_vdev(ibdev)->pdev->dev,
+ "unsupported device modify mask %#x\n", mask);
+ return -EOPNOTSUPP;
+ }
+
+ if (mask & IB_DEVICE_MODIFY_NODE_DESC) {
+ spin_lock_irqsave(&to_vdev(ibdev)->desc_lock, flags);
+ memcpy(ibdev->node_desc, props->node_desc, 64);
+ spin_unlock_irqrestore(&to_vdev(ibdev)->desc_lock, flags);
+ }
+
+ if (mask & IB_DEVICE_MODIFY_SYS_IMAGE_GUID) {
+ mutex_lock(&to_vdev(ibdev)->port_mutex);
+ to_vdev(ibdev)->sys_image_guid =
+ cpu_to_be64(props->sys_image_guid);
+ mutex_unlock(&to_vdev(ibdev)->port_mutex);
+ }
+
+ return 0;
+}
+
+/**
+ * pvrdma_modify_port - modify device port attributes
+ * @ibdev: the device to modify
+ * @port: the port number
+ * @mask: attributes to modify
+ * @props: the device properties
+ *
+ * @return: 0 on success, otherwise negative errno
+ */
+int pvrdma_modify_port(struct ib_device *ibdev, u8 port, int mask,
+ struct ib_port_modify *props)
+{
+ struct ib_port_attr attr;
+ struct pvrdma_dev *vdev = to_vdev(ibdev);
+ int ret;
+
+ if (mask & ~IB_PORT_SHUTDOWN) {
+ dev_warn(&vdev->pdev->dev,
+ "unsupported port modify mask %#x\n", mask);
+ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&vdev->port_mutex);
+ ret = pvrdma_query_port(ibdev, port, &attr);
+ if (ret)
+ goto out;
+
+ vdev->port_cap_mask |= props->set_port_cap_mask;
+ vdev->port_cap_mask &= ~props->clr_port_cap_mask;
+
+ if (mask & IB_PORT_SHUTDOWN)
+ vdev->ib_active = false;
+
+out:
+ mutex_unlock(&vdev->port_mutex);
+ return ret;
+}
+
+/**
+ * pvrdma_alloc_ucontext - allocate ucontext
+ * @ibdev: the IB device
+ * @udata: user data
+ *
+ * @return: the ib_ucontext pointer on success, otherwise errno.
+ */
+struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev,
+ struct ib_udata *udata)
+{
+ struct pvrdma_dev *vdev = to_vdev(ibdev);
+ struct pvrdma_ucontext *context;
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_uc *cmd = &req.create_uc;
+ struct pvrdma_cmd_create_uc_resp *resp = &rsp.create_uc_resp;
+ struct pvrdma_alloc_ucontext_resp uresp;
+ int ret;
+ void *ptr;
+
+ if (!vdev->ib_active)
+ return ERR_PTR(-EAGAIN);
+
+ context = kmalloc(sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return ERR_PTR(-ENOMEM);
+
+ context->dev = vdev;
+ ret = pvrdma_uar_alloc(vdev, &context->uar);
+ if (ret) {
+ kfree(context);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* get ctx_handle from host */
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->pfn = context->uar.pfn;
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_UC;
+ ret = pvrdma_cmd_post(vdev, &req, &rsp, PVRDMA_CMD_CREATE_UC_RESP);
+ if (ret < 0) {
+ dev_warn(&vdev->pdev->dev,
+ "could not create ucontext, error: %d\n", ret);
+ ptr = ERR_PTR(ret);
+ goto err;
+ }
+
+ context->ctx_handle = resp->ctx_handle;
+
+ /* copy back to user */
+ uresp.qp_tab_size = vdev->dsr->caps.max_qp;
+ ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
+ if (ret) {
+ pvrdma_uar_free(vdev, &context->uar);
+ context->ibucontext.device = ibdev;
+ pvrdma_dealloc_ucontext(&context->ibucontext);
+ return ERR_PTR(-EFAULT);
+ }
+
+ return &context->ibucontext;
+
+err:
+ pvrdma_uar_free(vdev, &context->uar);
+ kfree(context);
+ return ptr;
+}
+
+/**
+ * pvrdma_dealloc_ucontext - deallocate ucontext
+ * @ibcontext: the ucontext
+ *
+ * @return: 0 on success, otherwise errno.
+ */
+int pvrdma_dealloc_ucontext(struct ib_ucontext *ibcontext)
+{
+ struct pvrdma_ucontext *context = to_vucontext(ibcontext);
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_destroy_uc *cmd = &req.destroy_uc;
+ int ret;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_DESTROY_UC;
+ cmd->ctx_handle = context->ctx_handle;
+
+ ret = pvrdma_cmd_post(context->dev, &req, NULL, 0);
+ if (ret < 0)
+ dev_warn(&context->dev->pdev->dev,
+ "destroy ucontext failed, error: %d\n", ret);
+
+ /* Free the UAR even if the device command failed */
+ pvrdma_uar_free(to_vdev(ibcontext->device), &context->uar);
+ kfree(context);
+
+ return ret;
+}
+
+/**
+ * pvrdma_mmap - create mmap region
+ * @ibcontext: the user context
+ * @vma: the VMA
+ *
+ * @return: 0 on success, otherwise errno.
+ */
+int pvrdma_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
+{
+ struct pvrdma_ucontext *context = to_vucontext(ibcontext);
+ unsigned long start = vma->vm_start;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ dev_dbg(&context->dev->pdev->dev, "create mmap region\n");
+
+ if ((size != PAGE_SIZE) || (offset & ~PAGE_MASK)) {
+ dev_warn(&context->dev->pdev->dev,
+ "invalid params for mmap region\n");
+ return -EINVAL;
+ }
+
+ /* Map UAR to kernel space, VM_LOCKED? */
+ vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (io_remap_pfn_range(vma, start, context->uar.pfn, size,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+/**
+ * pvrdma_alloc_pd - allocate protection domain
+ * @ibdev: the IB device
+ * @context: user context
+ * @udata: user data
+ *
+ * @return: the ib_pd protection domain pointer on success, otherwise errno.
+ */
+struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
+ struct ib_ucontext *context,
+ struct ib_udata *udata)
+{
+ struct pvrdma_pd *pd;
+ struct pvrdma_dev *dev = to_vdev(ibdev);
+ union pvrdma_cmd_req req;
+ union pvrdma_cmd_resp rsp;
+ struct pvrdma_cmd_create_pd *cmd = &req.create_pd;
+ struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp;
+ int ret;
+ void *ptr;
+
+ /* Check allowed max pds */
+ if (!atomic_add_unless(&dev->num_pds, 1, dev->dsr->caps.max_pd))
+ return ERR_PTR(-ENOMEM);
+
+ pd = kmalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ ptr = ERR_PTR(-ENOMEM);
+ goto err;
+ }
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_CREATE_PD;
+ cmd->ctx_handle = (context) ? to_vucontext(context)->ctx_handle : 0;
+ ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_PD_RESP);
+ if (ret < 0) {
+ dev_warn(&dev->pdev->dev,
+ "failed to allocate protection domain, error: %d\n",
+ ret);
+ ptr = ERR_PTR(ret);
+ goto freepd;
+ }
+
+ pd->privileged = !context;
+ pd->pd_handle = resp->pd_handle;
+ pd->pdn = resp->pd_handle;
+
+ if (context) {
+ if (ib_copy_to_udata(udata, &pd->pdn, sizeof(__u32))) {
+ dev_warn(&dev->pdev->dev,
+ "failed to copy back protection domain\n");
+ pvrdma_dealloc_pd(&pd->ibpd);
+ return ERR_PTR(-EFAULT);
+ }
+ }
+
+ /* u32 pd handle */
+ return &pd->ibpd;
+
+freepd:
+ kfree(pd);
+err:
+ atomic_dec(&dev->num_pds);
+ return ptr;
+}
+
+/**
+ * pvrdma_dealloc_pd - deallocate protection domain
+ * @pd: the protection domain to be released
+ *
+ * @return: 0 on success, otherwise errno.
+ */
+int pvrdma_dealloc_pd(struct ib_pd *pd)
+{
+ struct pvrdma_dev *dev = to_vdev(pd->device);
+ union pvrdma_cmd_req req;
+ struct pvrdma_cmd_destroy_pd *cmd = &req.destroy_pd;
+ int ret;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.cmd = PVRDMA_CMD_DESTROY_PD;
+ cmd->pd_handle = to_vpd(pd)->pd_handle;
+
+ ret = pvrdma_cmd_post(dev, &req, NULL, 0);
+ if (ret)
+ dev_warn(&dev->pdev->dev,
+ "could not dealloc protection domain, error: %d\n",
+ ret);
+
+ kfree(to_vpd(pd));
+ atomic_dec(&dev->num_pds);
+
+ return 0;
+}
+
+/**
+ * pvrdma_create_ah - create an address handle
+ * @pd: the protection domain
+ * @ah_attr: the attributes of the AH
+ * @udata: user data blob
+ *
+ * @return: the ib_ah pointer on success, otherwise errno.
+ */
+struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata)
+{
+ struct pvrdma_dev *dev = to_vdev(pd->device);
+ struct pvrdma_ah *ah;
+ enum rdma_link_layer ll;
+
+ if (!(ah_attr->ah_flags & IB_AH_GRH))
+ return ERR_PTR(-EINVAL);
+
+ ll = rdma_port_get_link_layer(pd->device, ah_attr->port_num);
+
+ if (ll != IB_LINK_LAYER_ETHERNET ||
+ rdma_is_multicast_addr((struct in6_addr *)ah_attr->grh.dgid.raw))
+ return ERR_PTR(-EINVAL);
+
+ if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah))
+ return ERR_PTR(-ENOMEM);
+
+ ah = kzalloc(sizeof(*ah), GFP_KERNEL);
+ if (!ah) {
+ atomic_dec(&dev->num_ahs);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ah->av.port_pd = to_vpd(pd)->pd_handle | (ah_attr->port_num << 24);
+ ah->av.src_path_bits = ah_attr->src_path_bits;
+ ah->av.src_path_bits |= 0x80;
+ ah->av.gid_index = ah_attr->grh.sgid_index;
+ ah->av.hop_limit = ah_attr->grh.hop_limit;
+ ah->av.sl_tclass_flowlabel = (ah_attr->grh.traffic_class << 20) |
+ ah_attr->grh.flow_label;
+ memcpy(ah->av.dgid, ah_attr->grh.dgid.raw, 16);
+ memcpy(ah->av.dmac, ah_attr->dmac, 6);
+
+ ah->ibah.device = pd->device;
+ ah->ibah.pd = pd;
+ ah->ibah.uobject = NULL;
+
+ return &ah->ibah;
+}
+
+/**
+ * pvrdma_destroy_ah - destroy an address handle
+ * @ah: the address handle to destroyed
+ *
+ * @return: 0 on success.
+ */
+int pvrdma_destroy_ah(struct ib_ah *ah)
+{
+ struct pvrdma_dev *dev = to_vdev(ah->device);
+
+ kfree(to_vah(ah));
+ atomic_dec(&dev->num_ahs);
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
new file mode 100644
index 000000000000..bfbe96b56255
--- /dev/null
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PVRDMA_VERBS_H__
+#define __PVRDMA_VERBS_H__
+
+#include <linux/types.h>
+
+union pvrdma_gid {
+ u8 raw[16];
+ struct {
+ __be64 subnet_prefix;
+ __be64 interface_id;
+ } global;
+};
+
+enum pvrdma_link_layer {
+ PVRDMA_LINK_LAYER_UNSPECIFIED,
+ PVRDMA_LINK_LAYER_INFINIBAND,
+ PVRDMA_LINK_LAYER_ETHERNET,
+};
+
+enum pvrdma_mtu {
+ PVRDMA_MTU_256 = 1,
+ PVRDMA_MTU_512 = 2,
+ PVRDMA_MTU_1024 = 3,
+ PVRDMA_MTU_2048 = 4,
+ PVRDMA_MTU_4096 = 5,
+};
+
+static inline int pvrdma_mtu_enum_to_int(enum pvrdma_mtu mtu)
+{
+ switch (mtu) {
+ case PVRDMA_MTU_256: return 256;
+ case PVRDMA_MTU_512: return 512;
+ case PVRDMA_MTU_1024: return 1024;
+ case PVRDMA_MTU_2048: return 2048;
+ case PVRDMA_MTU_4096: return 4096;
+ default: return -1;
+ }
+}
+
+static inline enum pvrdma_mtu pvrdma_mtu_int_to_enum(int mtu)
+{
+ switch (mtu) {
+ case 256: return PVRDMA_MTU_256;
+ case 512: return PVRDMA_MTU_512;
+ case 1024: return PVRDMA_MTU_1024;
+ case 2048: return PVRDMA_MTU_2048;
+ case 4096:
+ default: return PVRDMA_MTU_4096;
+ }
+}
+
+enum pvrdma_port_state {
+ PVRDMA_PORT_NOP = 0,
+ PVRDMA_PORT_DOWN = 1,
+ PVRDMA_PORT_INIT = 2,
+ PVRDMA_PORT_ARMED = 3,
+ PVRDMA_PORT_ACTIVE = 4,
+ PVRDMA_PORT_ACTIVE_DEFER = 5,
+};
+
+enum pvrdma_port_cap_flags {
+ PVRDMA_PORT_SM = 1 << 1,
+ PVRDMA_PORT_NOTICE_SUP = 1 << 2,
+ PVRDMA_PORT_TRAP_SUP = 1 << 3,
+ PVRDMA_PORT_OPT_IPD_SUP = 1 << 4,
+ PVRDMA_PORT_AUTO_MIGR_SUP = 1 << 5,
+ PVRDMA_PORT_SL_MAP_SUP = 1 << 6,
+ PVRDMA_PORT_MKEY_NVRAM = 1 << 7,
+ PVRDMA_PORT_PKEY_NVRAM = 1 << 8,
+ PVRDMA_PORT_LED_INFO_SUP = 1 << 9,
+ PVRDMA_PORT_SM_DISABLED = 1 << 10,
+ PVRDMA_PORT_SYS_IMAGE_GUID_SUP = 1 << 11,
+ PVRDMA_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12,
+ PVRDMA_PORT_EXTENDED_SPEEDS_SUP = 1 << 14,
+ PVRDMA_PORT_CM_SUP = 1 << 16,
+ PVRDMA_PORT_SNMP_TUNNEL_SUP = 1 << 17,
+ PVRDMA_PORT_REINIT_SUP = 1 << 18,
+ PVRDMA_PORT_DEVICE_MGMT_SUP = 1 << 19,
+ PVRDMA_PORT_VENDOR_CLASS_SUP = 1 << 20,
+ PVRDMA_PORT_DR_NOTICE_SUP = 1 << 21,
+ PVRDMA_PORT_CAP_MASK_NOTICE_SUP = 1 << 22,
+ PVRDMA_PORT_BOOT_MGMT_SUP = 1 << 23,
+ PVRDMA_PORT_LINK_LATENCY_SUP = 1 << 24,
+ PVRDMA_PORT_CLIENT_REG_SUP = 1 << 25,
+ PVRDMA_PORT_IP_BASED_GIDS = 1 << 26,
+ PVRDMA_PORT_CAP_FLAGS_MAX = PVRDMA_PORT_IP_BASED_GIDS,
+};
+
+enum pvrdma_port_width {
+ PVRDMA_WIDTH_1X = 1,
+ PVRDMA_WIDTH_4X = 2,
+ PVRDMA_WIDTH_8X = 4,
+ PVRDMA_WIDTH_12X = 8,
+};
+
+static inline int pvrdma_width_enum_to_int(enum pvrdma_port_width width)
+{
+ switch (width) {
+ case PVRDMA_WIDTH_1X: return 1;
+ case PVRDMA_WIDTH_4X: return 4;
+ case PVRDMA_WIDTH_8X: return 8;
+ case PVRDMA_WIDTH_12X: return 12;
+ default: return -1;
+ }
+}
+
+enum pvrdma_port_speed {
+ PVRDMA_SPEED_SDR = 1,
+ PVRDMA_SPEED_DDR = 2,
+ PVRDMA_SPEED_QDR = 4,
+ PVRDMA_SPEED_FDR10 = 8,
+ PVRDMA_SPEED_FDR = 16,
+ PVRDMA_SPEED_EDR = 32,
+};
+
+struct pvrdma_port_attr {
+ enum pvrdma_port_state state;
+ enum pvrdma_mtu max_mtu;
+ enum pvrdma_mtu active_mtu;
+ u32 gid_tbl_len;
+ u32 port_cap_flags;
+ u32 max_msg_sz;
+ u32 bad_pkey_cntr;
+ u32 qkey_viol_cntr;
+ u16 pkey_tbl_len;
+ u16 lid;
+ u16 sm_lid;
+ u8 lmc;
+ u8 max_vl_num;
+ u8 sm_sl;
+ u8 subnet_timeout;
+ u8 init_type_reply;
+ u8 active_width;
+ u8 active_speed;
+ u8 phys_state;
+ u8 reserved[2];
+};
+
+struct pvrdma_global_route {
+ union pvrdma_gid dgid;
+ u32 flow_label;
+ u8 sgid_index;
+ u8 hop_limit;
+ u8 traffic_class;
+ u8 reserved;
+};
+
+struct pvrdma_grh {
+ __be32 version_tclass_flow;
+ __be16 paylen;
+ u8 next_hdr;
+ u8 hop_limit;
+ union pvrdma_gid sgid;
+ union pvrdma_gid dgid;
+};
+
+enum pvrdma_ah_flags {
+ PVRDMA_AH_GRH = 1,
+};
+
+enum pvrdma_rate {
+ PVRDMA_RATE_PORT_CURRENT = 0,
+ PVRDMA_RATE_2_5_GBPS = 2,
+ PVRDMA_RATE_5_GBPS = 5,
+ PVRDMA_RATE_10_GBPS = 3,
+ PVRDMA_RATE_20_GBPS = 6,
+ PVRDMA_RATE_30_GBPS = 4,
+ PVRDMA_RATE_40_GBPS = 7,
+ PVRDMA_RATE_60_GBPS = 8,
+ PVRDMA_RATE_80_GBPS = 9,
+ PVRDMA_RATE_120_GBPS = 10,
+ PVRDMA_RATE_14_GBPS = 11,
+ PVRDMA_RATE_56_GBPS = 12,
+ PVRDMA_RATE_112_GBPS = 13,
+ PVRDMA_RATE_168_GBPS = 14,
+ PVRDMA_RATE_25_GBPS = 15,
+ PVRDMA_RATE_100_GBPS = 16,
+ PVRDMA_RATE_200_GBPS = 17,
+ PVRDMA_RATE_300_GBPS = 18,
+};
+
+struct pvrdma_ah_attr {
+ struct pvrdma_global_route grh;
+ u16 dlid;
+ u16 vlan_id;
+ u8 sl;
+ u8 src_path_bits;
+ u8 static_rate;
+ u8 ah_flags;
+ u8 port_num;
+ u8 dmac[6];
+ u8 reserved;
+};
+
+enum pvrdma_cq_notify_flags {
+ PVRDMA_CQ_SOLICITED = 1 << 0,
+ PVRDMA_CQ_NEXT_COMP = 1 << 1,
+ PVRDMA_CQ_SOLICITED_MASK = PVRDMA_CQ_SOLICITED |
+ PVRDMA_CQ_NEXT_COMP,
+ PVRDMA_CQ_REPORT_MISSED_EVENTS = 1 << 2,
+};
+
+struct pvrdma_qp_cap {
+ u32 max_send_wr;
+ u32 max_recv_wr;
+ u32 max_send_sge;
+ u32 max_recv_sge;
+ u32 max_inline_data;
+ u32 reserved;
+};
+
+enum pvrdma_sig_type {
+ PVRDMA_SIGNAL_ALL_WR,
+ PVRDMA_SIGNAL_REQ_WR,
+};
+
+enum pvrdma_qp_type {
+ PVRDMA_QPT_SMI,
+ PVRDMA_QPT_GSI,
+ PVRDMA_QPT_RC,
+ PVRDMA_QPT_UC,
+ PVRDMA_QPT_UD,
+ PVRDMA_QPT_RAW_IPV6,
+ PVRDMA_QPT_RAW_ETHERTYPE,
+ PVRDMA_QPT_RAW_PACKET = 8,
+ PVRDMA_QPT_XRC_INI = 9,
+ PVRDMA_QPT_XRC_TGT,
+ PVRDMA_QPT_MAX,
+};
+
+enum pvrdma_qp_create_flags {
+ PVRDMA_QP_CREATE_IPOPVRDMA_UD_LSO = 1 << 0,
+ PVRDMA_QP_CREATE_BLOCK_MULTICAST_LOOPBACK = 1 << 1,
+};
+
+enum pvrdma_qp_attr_mask {
+ PVRDMA_QP_STATE = 1 << 0,
+ PVRDMA_QP_CUR_STATE = 1 << 1,
+ PVRDMA_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2,
+ PVRDMA_QP_ACCESS_FLAGS = 1 << 3,
+ PVRDMA_QP_PKEY_INDEX = 1 << 4,
+ PVRDMA_QP_PORT = 1 << 5,
+ PVRDMA_QP_QKEY = 1 << 6,
+ PVRDMA_QP_AV = 1 << 7,
+ PVRDMA_QP_PATH_MTU = 1 << 8,
+ PVRDMA_QP_TIMEOUT = 1 << 9,
+ PVRDMA_QP_RETRY_CNT = 1 << 10,
+ PVRDMA_QP_RNR_RETRY = 1 << 11,
+ PVRDMA_QP_RQ_PSN = 1 << 12,
+ PVRDMA_QP_MAX_QP_RD_ATOMIC = 1 << 13,
+ PVRDMA_QP_ALT_PATH = 1 << 14,
+ PVRDMA_QP_MIN_RNR_TIMER = 1 << 15,
+ PVRDMA_QP_SQ_PSN = 1 << 16,
+ PVRDMA_QP_MAX_DEST_RD_ATOMIC = 1 << 17,
+ PVRDMA_QP_PATH_MIG_STATE = 1 << 18,
+ PVRDMA_QP_CAP = 1 << 19,
+ PVRDMA_QP_DEST_QPN = 1 << 20,
+ PVRDMA_QP_ATTR_MASK_MAX = PVRDMA_QP_DEST_QPN,
+};
+
+enum pvrdma_qp_state {
+ PVRDMA_QPS_RESET,
+ PVRDMA_QPS_INIT,
+ PVRDMA_QPS_RTR,
+ PVRDMA_QPS_RTS,
+ PVRDMA_QPS_SQD,
+ PVRDMA_QPS_SQE,
+ PVRDMA_QPS_ERR,
+};
+
+enum pvrdma_mig_state {
+ PVRDMA_MIG_MIGRATED,
+ PVRDMA_MIG_REARM,
+ PVRDMA_MIG_ARMED,
+};
+
+enum pvrdma_mw_type {
+ PVRDMA_MW_TYPE_1 = 1,
+ PVRDMA_MW_TYPE_2 = 2,
+};
+
+struct pvrdma_qp_attr {
+ enum pvrdma_qp_state qp_state;
+ enum pvrdma_qp_state cur_qp_state;
+ enum pvrdma_mtu path_mtu;
+ enum pvrdma_mig_state path_mig_state;
+ u32 qkey;
+ u32 rq_psn;
+ u32 sq_psn;
+ u32 dest_qp_num;
+ u32 qp_access_flags;
+ u16 pkey_index;
+ u16 alt_pkey_index;
+ u8 en_sqd_async_notify;
+ u8 sq_draining;
+ u8 max_rd_atomic;
+ u8 max_dest_rd_atomic;
+ u8 min_rnr_timer;
+ u8 port_num;
+ u8 timeout;
+ u8 retry_cnt;
+ u8 rnr_retry;
+ u8 alt_port_num;
+ u8 alt_timeout;
+ u8 reserved[5];
+ struct pvrdma_qp_cap cap;
+ struct pvrdma_ah_attr ah_attr;
+ struct pvrdma_ah_attr alt_ah_attr;
+};
+
+enum pvrdma_send_flags {
+ PVRDMA_SEND_FENCE = 1 << 0,
+ PVRDMA_SEND_SIGNALED = 1 << 1,
+ PVRDMA_SEND_SOLICITED = 1 << 2,
+ PVRDMA_SEND_INLINE = 1 << 3,
+ PVRDMA_SEND_IP_CSUM = 1 << 4,
+ PVRDMA_SEND_FLAGS_MAX = PVRDMA_SEND_IP_CSUM,
+};
+
+enum pvrdma_access_flags {
+ PVRDMA_ACCESS_LOCAL_WRITE = 1 << 0,
+ PVRDMA_ACCESS_REMOTE_WRITE = 1 << 1,
+ PVRDMA_ACCESS_REMOTE_READ = 1 << 2,
+ PVRDMA_ACCESS_REMOTE_ATOMIC = 1 << 3,
+ PVRDMA_ACCESS_MW_BIND = 1 << 4,
+ PVRDMA_ZERO_BASED = 1 << 5,
+ PVRDMA_ACCESS_ON_DEMAND = 1 << 6,
+ PVRDMA_ACCESS_FLAGS_MAX = PVRDMA_ACCESS_ON_DEMAND,
+};
+
+int pvrdma_query_device(struct ib_device *ibdev,
+ struct ib_device_attr *props,
+ struct ib_udata *udata);
+int pvrdma_query_port(struct ib_device *ibdev, u8 port,
+ struct ib_port_attr *props);
+int pvrdma_query_gid(struct ib_device *ibdev, u8 port,
+ int index, union ib_gid *gid);
+int pvrdma_query_pkey(struct ib_device *ibdev, u8 port,
+ u16 index, u16 *pkey);
+enum rdma_link_layer pvrdma_port_link_layer(struct ib_device *ibdev,
+ u8 port);
+int pvrdma_modify_device(struct ib_device *ibdev, int mask,
+ struct ib_device_modify *props);
+int pvrdma_modify_port(struct ib_device *ibdev, u8 port,
+ int mask, struct ib_port_modify *props);
+int pvrdma_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
+struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev,
+ struct ib_udata *udata);
+int pvrdma_dealloc_ucontext(struct ib_ucontext *context);
+struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
+ struct ib_ucontext *context,
+ struct ib_udata *udata);
+int pvrdma_dealloc_pd(struct ib_pd *ibpd);
+struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc);
+struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ u64 virt_addr, int access_flags,
+ struct ib_udata *udata);
+int pvrdma_dereg_mr(struct ib_mr *mr);
+struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+ u32 max_num_sg);
+int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
+ int sg_nents, unsigned int *sg_offset);
+int pvrdma_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
+int pvrdma_resize_cq(struct ib_cq *ibcq, int entries,
+ struct ib_udata *udata);
+struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *context,
+ struct ib_udata *udata);
+int pvrdma_resize_cq(struct ib_cq *ibcq, int entries,
+ struct ib_udata *udata);
+int pvrdma_destroy_cq(struct ib_cq *cq);
+int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
+struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata);
+int pvrdma_destroy_ah(struct ib_ah *ah);
+struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata);
+int pvrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata);
+int pvrdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr);
+int pvrdma_destroy_qp(struct ib_qp *qp);
+int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr);
+int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr);
+
+#endif /* __PVRDMA_VERBS_H__ */
diff --git a/drivers/infiniband/sw/rdmavt/cq.c b/drivers/infiniband/sw/rdmavt/cq.c
index 6d9904a4a0ab..7aa7a4e312f1 100644
--- a/drivers/infiniband/sw/rdmavt/cq.c
+++ b/drivers/infiniband/sw/rdmavt/cq.c
@@ -119,18 +119,17 @@ void rvt_cq_enter(struct rvt_cq *cq, struct ib_wc *entry, bool solicited)
if (cq->notify == IB_CQ_NEXT_COMP ||
(cq->notify == IB_CQ_SOLICITED &&
(solicited || entry->status != IB_WC_SUCCESS))) {
- struct kthread_worker *worker;
/*
* This will cause send_complete() to be called in
* another thread.
*/
- smp_read_barrier_depends(); /* see rvt_cq_exit */
- worker = cq->rdi->worker;
- if (likely(worker)) {
+ spin_lock(&cq->rdi->n_cqs_lock);
+ if (likely(cq->rdi->worker)) {
cq->notify = RVT_CQ_NONE;
cq->triggered++;
- kthread_queue_work(worker, &cq->comptask);
+ kthread_queue_work(cq->rdi->worker, &cq->comptask);
}
+ spin_unlock(&cq->rdi->n_cqs_lock);
}
spin_unlock_irqrestore(&cq->lock, flags);
@@ -240,15 +239,15 @@ struct ib_cq *rvt_create_cq(struct ib_device *ibdev,
}
}
- spin_lock(&rdi->n_cqs_lock);
+ spin_lock_irq(&rdi->n_cqs_lock);
if (rdi->n_cqs_allocated == rdi->dparms.props.max_cq) {
- spin_unlock(&rdi->n_cqs_lock);
+ spin_unlock_irq(&rdi->n_cqs_lock);
ret = ERR_PTR(-ENOMEM);
goto bail_ip;
}
rdi->n_cqs_allocated++;
- spin_unlock(&rdi->n_cqs_lock);
+ spin_unlock_irq(&rdi->n_cqs_lock);
if (cq->ip) {
spin_lock_irq(&rdi->pending_lock);
@@ -296,9 +295,9 @@ int rvt_destroy_cq(struct ib_cq *ibcq)
struct rvt_dev_info *rdi = cq->rdi;
kthread_flush_work(&cq->comptask);
- spin_lock(&rdi->n_cqs_lock);
+ spin_lock_irq(&rdi->n_cqs_lock);
rdi->n_cqs_allocated--;
- spin_unlock(&rdi->n_cqs_lock);
+ spin_unlock_irq(&rdi->n_cqs_lock);
if (cq->ip)
kref_put(&cq->ip->ref, rvt_release_mmap_info);
else
@@ -504,33 +503,23 @@ int rvt_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
*/
int rvt_driver_cq_init(struct rvt_dev_info *rdi)
{
- int ret = 0;
int cpu;
- struct task_struct *task;
+ struct kthread_worker *worker;
if (rdi->worker)
return 0;
+
spin_lock_init(&rdi->n_cqs_lock);
- rdi->worker = kzalloc(sizeof(*rdi->worker), GFP_KERNEL);
- if (!rdi->worker)
- return -ENOMEM;
- kthread_init_worker(rdi->worker);
- task = kthread_create_on_node(
- kthread_worker_fn,
- rdi->worker,
- rdi->dparms.node,
- "%s", rdi->dparms.cq_name);
- if (IS_ERR(task)) {
- kfree(rdi->worker);
- rdi->worker = NULL;
- return PTR_ERR(task);
- }
- set_user_nice(task, MIN_NICE);
cpu = cpumask_first(cpumask_of_node(rdi->dparms.node));
- kthread_bind(task, cpu);
- wake_up_process(task);
- return ret;
+ worker = kthread_create_worker_on_cpu(cpu, 0,
+ "%s", rdi->dparms.cq_name);
+ if (IS_ERR(worker))
+ return PTR_ERR(worker);
+
+ set_user_nice(worker->task, MIN_NICE);
+ rdi->worker = worker;
+ return 0;
}
/**
@@ -541,13 +530,15 @@ void rvt_cq_exit(struct rvt_dev_info *rdi)
{
struct kthread_worker *worker;
+ /* block future queuing from send_complete() */
+ spin_lock_irq(&rdi->n_cqs_lock);
worker = rdi->worker;
- if (!worker)
+ if (!worker) {
+ spin_unlock_irq(&rdi->n_cqs_lock);
return;
- /* blocks future queuing from send_complete() */
+ }
rdi->worker = NULL;
- smp_wmb(); /* See rdi_cq_enter */
- kthread_flush_worker(worker);
- kthread_stop(worker->task);
- kfree(worker);
+ spin_unlock_irq(&rdi->n_cqs_lock);
+
+ kthread_destroy_worker(worker);
}
diff --git a/drivers/infiniband/sw/rdmavt/mcast.c b/drivers/infiniband/sw/rdmavt/mcast.c
index 983d319ac976..05c8c2afb0e3 100644
--- a/drivers/infiniband/sw/rdmavt/mcast.c
+++ b/drivers/infiniband/sw/rdmavt/mcast.c
@@ -81,7 +81,7 @@ static struct rvt_mcast_qp *rvt_mcast_qp_alloc(struct rvt_qp *qp)
goto bail;
mqp->qp = qp;
- atomic_inc(&qp->refcount);
+ rvt_get_qp(qp);
bail:
return mqp;
@@ -92,8 +92,7 @@ static void rvt_mcast_qp_free(struct rvt_mcast_qp *mqp)
struct rvt_qp *qp = mqp->qp;
/* Notify hfi1_destroy_qp() if it is waiting. */
- if (atomic_dec_and_test(&qp->refcount))
- wake_up(&qp->wait);
+ rvt_put_qp(qp);
kfree(mqp);
}
diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c
index 46b64970058e..52fd15276ee6 100644
--- a/drivers/infiniband/sw/rdmavt/mr.c
+++ b/drivers/infiniband/sw/rdmavt/mr.c
@@ -51,6 +51,7 @@
#include <rdma/rdma_vt.h>
#include "vt.h"
#include "mr.h"
+#include "trace.h"
/**
* rvt_driver_mr_init - Init MR resources per driver
@@ -84,6 +85,7 @@ int rvt_driver_mr_init(struct rvt_dev_info *rdi)
lkey_table_size = rdi->dparms.lkey_table_size;
}
rdi->lkey_table.max = 1 << lkey_table_size;
+ rdi->lkey_table.shift = 32 - lkey_table_size;
lk_tab_size = rdi->lkey_table.max * sizeof(*rdi->lkey_table.table);
rdi->lkey_table.table = (struct rvt_mregion __rcu **)
vmalloc_node(lk_tab_size, rdi->dparms.node);
@@ -402,6 +404,7 @@ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
}
mr->mr.map[m]->segs[n].vaddr = vaddr;
mr->mr.map[m]->segs[n].length = umem->page_size;
+ trace_rvt_mr_user_seg(&mr->mr, m, n, vaddr, umem->page_size);
n++;
if (n == RVT_SEGSZ) {
m++;
@@ -506,6 +509,7 @@ static int rvt_set_page(struct ib_mr *ibmr, u64 addr)
n = mapped_segs % RVT_SEGSZ;
mr->mr.map[m]->segs[n].vaddr = (void *)addr;
mr->mr.map[m]->segs[n].length = ps;
+ trace_rvt_mr_page_seg(&mr->mr, m, n, (void *)addr, ps);
mr->mr.length += ps;
return 0;
@@ -692,6 +696,7 @@ int rvt_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
for (i = 0; i < list_len; i++) {
fmr->mr.map[m]->segs[n].vaddr = (void *)page_list[i];
fmr->mr.map[m]->segs[n].length = ps;
+ trace_rvt_mr_fmr_seg(&fmr->mr, m, n, (void *)page_list[i], ps);
if (++n == RVT_SEGSZ) {
m++;
n = 0;
@@ -774,7 +779,6 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
struct rvt_mregion *mr;
unsigned n, m;
size_t off;
- struct rvt_dev_info *dev = ib_to_rvt(pd->ibpd.device);
/*
* We use LKEY == zero for kernel virtual addresses
@@ -782,12 +786,14 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
*/
rcu_read_lock();
if (sge->lkey == 0) {
+ struct rvt_dev_info *dev = ib_to_rvt(pd->ibpd.device);
+
if (pd->user)
goto bail;
mr = rcu_dereference(dev->dma_mr);
if (!mr)
goto bail;
- atomic_inc(&mr->refcount);
+ rvt_get_mr(mr);
rcu_read_unlock();
isge->mr = mr;
@@ -798,8 +804,7 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
isge->n = 0;
goto ok;
}
- mr = rcu_dereference(
- rkt->table[(sge->lkey >> (32 - dev->dparms.lkey_table_size))]);
+ mr = rcu_dereference(rkt->table[sge->lkey >> rkt->shift]);
if (unlikely(!mr || atomic_read(&mr->lkey_invalid) ||
mr->lkey != sge->lkey || mr->pd != &pd->ibpd))
goto bail;
@@ -809,7 +814,7 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,
off + sge->length > mr->length ||
(mr->access_flags & acc) != acc))
goto bail;
- atomic_inc(&mr->refcount);
+ rvt_get_mr(mr);
rcu_read_unlock();
off += mr->offset;
@@ -887,7 +892,7 @@ int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge,
mr = rcu_dereference(rdi->dma_mr);
if (!mr)
goto bail;
- atomic_inc(&mr->refcount);
+ rvt_get_mr(mr);
rcu_read_unlock();
sge->mr = mr;
@@ -899,8 +904,7 @@ int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge,
goto ok;
}
- mr = rcu_dereference(
- rkt->table[(rkey >> (32 - dev->dparms.lkey_table_size))]);
+ mr = rcu_dereference(rkt->table[rkey >> rkt->shift]);
if (unlikely(!mr || atomic_read(&mr->lkey_invalid) ||
mr->lkey != rkey || qp->ibqp.pd != mr->pd))
goto bail;
@@ -909,7 +913,7 @@ int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge,
if (unlikely(vaddr < mr->iova || off + len > mr->length ||
(mr->access_flags & acc) == 0))
goto bail;
- atomic_inc(&mr->refcount);
+ rvt_get_mr(mr);
rcu_read_unlock();
off += mr->offset;
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 6500c3b5a89c..2a13ac660f2b 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -76,6 +76,23 @@ const int ib_rvt_state_ops[IB_QPS_ERR + 1] = {
};
EXPORT_SYMBOL(ib_rvt_state_ops);
+/*
+ * Translate ib_wr_opcode into ib_wc_opcode.
+ */
+const enum ib_wc_opcode ib_rvt_wc_opcode[] = {
+ [IB_WR_RDMA_WRITE] = IB_WC_RDMA_WRITE,
+ [IB_WR_RDMA_WRITE_WITH_IMM] = IB_WC_RDMA_WRITE,
+ [IB_WR_SEND] = IB_WC_SEND,
+ [IB_WR_SEND_WITH_IMM] = IB_WC_SEND,
+ [IB_WR_RDMA_READ] = IB_WC_RDMA_READ,
+ [IB_WR_ATOMIC_CMP_AND_SWP] = IB_WC_COMP_SWAP,
+ [IB_WR_ATOMIC_FETCH_AND_ADD] = IB_WC_FETCH_ADD,
+ [IB_WR_SEND_WITH_INV] = IB_WC_SEND,
+ [IB_WR_LOCAL_INV] = IB_WC_LOCAL_INV,
+ [IB_WR_REG_MR] = IB_WC_REG_MR
+};
+EXPORT_SYMBOL(ib_rvt_wc_opcode);
+
static void get_map_page(struct rvt_qpn_table *qpt,
struct rvt_qpn_map *map,
gfp_t gfp)
@@ -884,7 +901,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
return ret;
bail_ip:
- kref_put(&qp->ip->ref, rvt_release_mmap_info);
+ if (qp->ip)
+ kref_put(&qp->ip->ref, rvt_release_mmap_info);
bail_qpn:
free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num);
diff --git a/drivers/infiniband/sw/rdmavt/trace.h b/drivers/infiniband/sw/rdmavt/trace.h
index 6c0457db5499..e2d23acb6a7d 100644
--- a/drivers/infiniband/sw/rdmavt/trace.h
+++ b/drivers/infiniband/sw/rdmavt/trace.h
@@ -45,143 +45,10 @@
*
*/
-#undef TRACE_SYSTEM_VAR
-#define TRACE_SYSTEM_VAR rdmavt
-
-#if !defined(__RDMAVT_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
-#define __RDMAVT_TRACE_H
-
-#include <linux/tracepoint.h>
-#include <linux/trace_seq.h>
-
-#include <rdma/ib_verbs.h>
-#include <rdma/rdma_vt.h>
-
#define RDI_DEV_ENTRY(rdi) __string(dev, rdi->driver_f.get_card_name(rdi))
#define RDI_DEV_ASSIGN(rdi) __assign_str(dev, rdi->driver_f.get_card_name(rdi))
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM rdmavt
-
-TRACE_EVENT(rvt_dbg,
- TP_PROTO(struct rvt_dev_info *rdi,
- const char *msg),
- TP_ARGS(rdi, msg),
- TP_STRUCT__entry(
- RDI_DEV_ENTRY(rdi)
- __string(msg, msg)
- ),
- TP_fast_assign(
- RDI_DEV_ASSIGN(rdi);
- __assign_str(msg, msg);
- ),
- TP_printk("[%s]: %s", __get_str(dev), __get_str(msg))
-);
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM rvt_qphash
-DECLARE_EVENT_CLASS(rvt_qphash_template,
- TP_PROTO(struct rvt_qp *qp, u32 bucket),
- TP_ARGS(qp, bucket),
- TP_STRUCT__entry(
- RDI_DEV_ENTRY(ib_to_rvt(qp->ibqp.device))
- __field(u32, qpn)
- __field(u32, bucket)
- ),
- TP_fast_assign(
- RDI_DEV_ASSIGN(ib_to_rvt(qp->ibqp.device))
- __entry->qpn = qp->ibqp.qp_num;
- __entry->bucket = bucket;
- ),
- TP_printk(
- "[%s] qpn 0x%x bucket %u",
- __get_str(dev),
- __entry->qpn,
- __entry->bucket
- )
-);
-
-DEFINE_EVENT(rvt_qphash_template, rvt_qpinsert,
- TP_PROTO(struct rvt_qp *qp, u32 bucket),
- TP_ARGS(qp, bucket));
-
-DEFINE_EVENT(rvt_qphash_template, rvt_qpremove,
- TP_PROTO(struct rvt_qp *qp, u32 bucket),
- TP_ARGS(qp, bucket));
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM rvt_tx
-
-#define wr_opcode_name(opcode) { IB_WR_##opcode, #opcode }
-#define show_wr_opcode(opcode) \
-__print_symbolic(opcode, \
- wr_opcode_name(RDMA_WRITE), \
- wr_opcode_name(RDMA_WRITE_WITH_IMM), \
- wr_opcode_name(SEND), \
- wr_opcode_name(SEND_WITH_IMM), \
- wr_opcode_name(RDMA_READ), \
- wr_opcode_name(ATOMIC_CMP_AND_SWP), \
- wr_opcode_name(ATOMIC_FETCH_AND_ADD), \
- wr_opcode_name(LSO), \
- wr_opcode_name(SEND_WITH_INV), \
- wr_opcode_name(RDMA_READ_WITH_INV), \
- wr_opcode_name(LOCAL_INV), \
- wr_opcode_name(MASKED_ATOMIC_CMP_AND_SWP), \
- wr_opcode_name(MASKED_ATOMIC_FETCH_AND_ADD))
-
-#define POS_PRN \
-"[%s] wr_id %llx qpn %x psn 0x%x lpsn 0x%x length %u opcode 0x%.2x,%s size %u avail %u head %u last %u"
-
-TRACE_EVENT(
- rvt_post_one_wr,
- TP_PROTO(struct rvt_qp *qp, struct rvt_swqe *wqe),
- TP_ARGS(qp, wqe),
- TP_STRUCT__entry(
- RDI_DEV_ENTRY(ib_to_rvt(qp->ibqp.device))
- __field(u64, wr_id)
- __field(u32, qpn)
- __field(u32, psn)
- __field(u32, lpsn)
- __field(u32, length)
- __field(u32, opcode)
- __field(u32, size)
- __field(u32, avail)
- __field(u32, head)
- __field(u32, last)
- ),
- TP_fast_assign(
- RDI_DEV_ASSIGN(ib_to_rvt(qp->ibqp.device))
- __entry->wr_id = wqe->wr.wr_id;
- __entry->qpn = qp->ibqp.qp_num;
- __entry->psn = wqe->psn;
- __entry->lpsn = wqe->lpsn;
- __entry->length = wqe->length;
- __entry->opcode = wqe->wr.opcode;
- __entry->size = qp->s_size;
- __entry->avail = qp->s_avail;
- __entry->head = qp->s_head;
- __entry->last = qp->s_last;
- ),
- TP_printk(
- POS_PRN,
- __get_str(dev),
- __entry->wr_id,
- __entry->qpn,
- __entry->psn,
- __entry->lpsn,
- __entry->length,
- __entry->opcode, show_wr_opcode(__entry->opcode),
- __entry->size,
- __entry->avail,
- __entry->head,
- __entry->last
- )
-);
-
-#endif /* __RDMAVT_TRACE_H */
-
-#undef TRACE_INCLUDE_PATH
-#undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace
-#include <trace/define_trace.h>
+#include "trace_rvt.h"
+#include "trace_qp.h"
+#include "trace_tx.h"
+#include "trace_mr.h"
diff --git a/drivers/infiniband/sw/rdmavt/trace_mr.h b/drivers/infiniband/sw/rdmavt/trace_mr.h
new file mode 100644
index 000000000000..3318a6c36373
--- /dev/null
+++ b/drivers/infiniband/sw/rdmavt/trace_mr.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright(c) 2016 Intel Corporation.
+ *
+ * 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
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * BSD LICENSE
+ *
+ * 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 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.
+ *
+ */
+#if !defined(__RVT_TRACE_MR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define __RVT_TRACE_MR_H
+
+#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/rdma_vt.h>
+#include <rdma/rdmavt_mr.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rvt_mr
+DECLARE_EVENT_CLASS(
+ rvt_mr_template,
+ TP_PROTO(struct rvt_mregion *mr, u16 m, u16 n, void *v, size_t len),
+ TP_ARGS(mr, m, n, v, len),
+ TP_STRUCT__entry(
+ RDI_DEV_ENTRY(ib_to_rvt(mr->pd->device))
+ __field(void *, vaddr)
+ __field(struct page *, page)
+ __field(size_t, len)
+ __field(u32, lkey)
+ __field(u16, m)
+ __field(u16, n)
+ ),
+ TP_fast_assign(
+ RDI_DEV_ASSIGN(ib_to_rvt(mr->pd->device));
+ __entry->vaddr = v;
+ __entry->page = virt_to_page(v);
+ __entry->m = m;
+ __entry->n = n;
+ __entry->len = len;
+ ),
+ TP_printk(
+ "[%s] vaddr %p page %p m %u n %u len %ld",
+ __get_str(dev),
+ __entry->vaddr,
+ __entry->page,
+ __entry->m,
+ __entry->n,
+ __entry->len
+ )
+);
+
+DEFINE_EVENT(
+ rvt_mr_template, rvt_mr_page_seg,
+ TP_PROTO(struct rvt_mregion *mr, u16 m, u16 n, void *v, size_t len),
+ TP_ARGS(mr, m, n, v, len));
+
+DEFINE_EVENT(
+ rvt_mr_template, rvt_mr_fmr_seg,
+ TP_PROTO(struct rvt_mregion *mr, u16 m, u16 n, void *v, size_t len),
+ TP_ARGS(mr, m, n, v, len));
+
+DEFINE_EVENT(
+ rvt_mr_template, rvt_mr_user_seg,
+ TP_PROTO(struct rvt_mregion *mr, u16 m, u16 n, void *v, size_t len),
+ TP_ARGS(mr, m, n, v, len));
+
+#endif /* __RVT_TRACE_MR_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_mr
+#include <trace/define_trace.h>
diff --git a/drivers/infiniband/sw/rdmavt/trace_qp.h b/drivers/infiniband/sw/rdmavt/trace_qp.h
new file mode 100644
index 000000000000..4c77a3119bda
--- /dev/null
+++ b/drivers/infiniband/sw/rdmavt/trace_qp.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright(c) 2016 Intel Corporation.
+ *
+ * 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
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * BSD LICENSE
+ *
+ * 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 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.
+ *
+ */
+#if !defined(__RVT_TRACE_QP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define __RVT_TRACE_QP_H
+
+#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/rdma_vt.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rvt_qp
+
+DECLARE_EVENT_CLASS(rvt_qphash_template,
+ TP_PROTO(struct rvt_qp *qp, u32 bucket),
+ TP_ARGS(qp, bucket),
+ TP_STRUCT__entry(
+ RDI_DEV_ENTRY(ib_to_rvt(qp->ibqp.device))
+ __field(u32, qpn)
+ __field(u32, bucket)
+ ),
+ TP_fast_assign(
+ RDI_DEV_ASSIGN(ib_to_rvt(qp->ibqp.device))
+ __entry->qpn = qp->ibqp.qp_num;
+ __entry->bucket = bucket;
+ ),
+ TP_printk(
+ "[%s] qpn 0x%x bucket %u",
+ __get_str(dev),
+ __entry->qpn,
+ __entry->bucket
+ )
+);
+
+DEFINE_EVENT(rvt_qphash_template, rvt_qpinsert,
+ TP_PROTO(struct rvt_qp *qp, u32 bucket),
+ TP_ARGS(qp, bucket));
+
+DEFINE_EVENT(rvt_qphash_template, rvt_qpremove,
+ TP_PROTO(struct rvt_qp *qp, u32 bucket),
+ TP_ARGS(qp, bucket));
+
+
+#endif /* __RVT_TRACE_QP_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_qp
+#include <trace/define_trace.h>
+
diff --git a/drivers/infiniband/sw/rdmavt/trace_rvt.h b/drivers/infiniband/sw/rdmavt/trace_rvt.h
new file mode 100644
index 000000000000..746f33461d9a
--- /dev/null
+++ b/drivers/infiniband/sw/rdmavt/trace_rvt.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright(c) 2016 Intel Corporation.
+ *
+ * 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
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * BSD LICENSE
+ *
+ * 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 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.
+ *
+ */
+#if !defined(__RVT_TRACE_RVT_H) || defined(TRACE_HEADER_MULTI_READ)
+#define __RVT_TRACE_RVT_H
+
+#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/rdma_vt.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rvt
+
+TRACE_EVENT(rvt_dbg,
+ TP_PROTO(struct rvt_dev_info *rdi,
+ const char *msg),
+ TP_ARGS(rdi, msg),
+ TP_STRUCT__entry(
+ RDI_DEV_ENTRY(rdi)
+ __string(msg, msg)
+ ),
+ TP_fast_assign(
+ RDI_DEV_ASSIGN(rdi);
+ __assign_str(msg, msg);
+ ),
+ TP_printk("[%s]: %s", __get_str(dev), __get_str(msg))
+);
+
+#endif /* __RVT_TRACE_MISC_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_rvt
+#include <trace/define_trace.h>
+
diff --git a/drivers/infiniband/sw/rdmavt/trace_tx.h b/drivers/infiniband/sw/rdmavt/trace_tx.h
new file mode 100644
index 000000000000..0e03173662d8
--- /dev/null
+++ b/drivers/infiniband/sw/rdmavt/trace_tx.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright(c) 2016 Intel Corporation.
+ *
+ * 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
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * BSD LICENSE
+ *
+ * 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 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.
+ *
+ */
+#if !defined(__RVT_TRACE_TX_H) || defined(TRACE_HEADER_MULTI_READ)
+#define __RVT_TRACE_TX_H
+
+#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/rdma_vt.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rvt_tx
+
+#define wr_opcode_name(opcode) { IB_WR_##opcode, #opcode }
+#define show_wr_opcode(opcode) \
+__print_symbolic(opcode, \
+ wr_opcode_name(RDMA_WRITE), \
+ wr_opcode_name(RDMA_WRITE_WITH_IMM), \
+ wr_opcode_name(SEND), \
+ wr_opcode_name(SEND_WITH_IMM), \
+ wr_opcode_name(RDMA_READ), \
+ wr_opcode_name(ATOMIC_CMP_AND_SWP), \
+ wr_opcode_name(ATOMIC_FETCH_AND_ADD), \
+ wr_opcode_name(LSO), \
+ wr_opcode_name(SEND_WITH_INV), \
+ wr_opcode_name(RDMA_READ_WITH_INV), \
+ wr_opcode_name(LOCAL_INV), \
+ wr_opcode_name(MASKED_ATOMIC_CMP_AND_SWP), \
+ wr_opcode_name(MASKED_ATOMIC_FETCH_AND_ADD))
+
+#define POS_PRN \
+"[%s] wr_id %llx qpn %x psn 0x%x lpsn 0x%x length %u opcode 0x%.2x,%s size %u avail %u head %u last %u"
+
+TRACE_EVENT(
+ rvt_post_one_wr,
+ TP_PROTO(struct rvt_qp *qp, struct rvt_swqe *wqe),
+ TP_ARGS(qp, wqe),
+ TP_STRUCT__entry(
+ RDI_DEV_ENTRY(ib_to_rvt(qp->ibqp.device))
+ __field(u64, wr_id)
+ __field(u32, qpn)
+ __field(u32, psn)
+ __field(u32, lpsn)
+ __field(u32, length)
+ __field(u32, opcode)
+ __field(u32, size)
+ __field(u32, avail)
+ __field(u32, head)
+ __field(u32, last)
+ ),
+ TP_fast_assign(
+ RDI_DEV_ASSIGN(ib_to_rvt(qp->ibqp.device))
+ __entry->wr_id = wqe->wr.wr_id;
+ __entry->qpn = qp->ibqp.qp_num;
+ __entry->psn = wqe->psn;
+ __entry->lpsn = wqe->lpsn;
+ __entry->length = wqe->length;
+ __entry->opcode = wqe->wr.opcode;
+ __entry->size = qp->s_size;
+ __entry->avail = qp->s_avail;
+ __entry->head = qp->s_head;
+ __entry->last = qp->s_last;
+ ),
+ TP_printk(
+ POS_PRN,
+ __get_str(dev),
+ __entry->wr_id,
+ __entry->qpn,
+ __entry->psn,
+ __entry->lpsn,
+ __entry->length,
+ __entry->opcode, show_wr_opcode(__entry->opcode),
+ __entry->size,
+ __entry->avail,
+ __entry->head,
+ __entry->last
+ )
+);
+
+#endif /* __RVT_TRACE_TX_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_tx
+#include <trace/define_trace.h>
+
diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
index 6c5e29db88e3..cd27cbde7652 100644
--- a/drivers/infiniband/sw/rxe/rxe_comp.c
+++ b/drivers/infiniband/sw/rxe/rxe_comp.c
@@ -420,11 +420,12 @@ static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
(wqe->wr.send_flags & IB_SEND_SIGNALED) ||
(qp->req.state == QP_STATE_ERROR)) {
make_send_cqe(qp, wqe, &cqe);
+ advance_consumer(qp->sq.queue);
rxe_cq_post(qp->scq, &cqe, 0);
+ } else {
+ advance_consumer(qp->sq.queue);
}
- advance_consumer(qp->sq.queue);
-
/*
* we completed something so let req run again
* if it is trying to fence
@@ -510,6 +511,8 @@ int rxe_completer(void *arg)
struct rxe_pkt_info *pkt = NULL;
enum comp_state state;
+ rxe_add_ref(qp);
+
if (!qp->valid) {
while ((skb = skb_dequeue(&qp->resp_pkts))) {
rxe_drop_ref(qp);
@@ -739,11 +742,13 @@ exit:
/* we come here if we are done with processing and want the task to
* exit from the loop calling us
*/
+ rxe_drop_ref(qp);
return -EAGAIN;
done:
/* we come here if we have processed a packet we want the task to call
* us again to see if there is anything else to do
*/
+ rxe_drop_ref(qp);
return 0;
}
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
index 73849a5a91b3..efe4c6a35442 100644
--- a/drivers/infiniband/sw/rxe/rxe_loc.h
+++ b/drivers/infiniband/sw/rxe/rxe_loc.h
@@ -266,8 +266,6 @@ static inline int rxe_xmit_packet(struct rxe_dev *rxe, struct rxe_qp *qp,
return err;
}
- atomic_inc(&qp->skb_out);
-
if ((qp_type(qp) != IB_QPT_RC) &&
(pkt->mask & RXE_END_MASK)) {
pkt->wqe->state = wqe_state_done;
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index 1869152f1d23..d0faca294006 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -355,6 +355,9 @@ int rxe_mem_copy(struct rxe_mem *mem, u64 iova, void *addr, int length,
size_t offset;
u32 crc = crcp ? (*crcp) : 0;
+ if (length == 0)
+ return 0;
+
if (mem->type == RXE_MEM_TYPE_DMA) {
u8 *src, *dest;
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index ffff5a54cb34..16967cdb45df 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -46,7 +46,7 @@
#include "rxe_loc.h"
static LIST_HEAD(rxe_dev_list);
-static spinlock_t dev_list_lock; /* spinlock for device list */
+static DEFINE_SPINLOCK(dev_list_lock); /* spinlock for device list */
struct rxe_dev *net_to_rxe(struct net_device *ndev)
{
@@ -455,6 +455,8 @@ static int send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
return -EAGAIN;
}
+ if (pkt->qp)
+ atomic_inc(&pkt->qp->skb_out);
kfree_skb(skb);
return 0;
@@ -659,8 +661,6 @@ struct notifier_block rxe_net_notifier = {
int rxe_net_ipv4_init(void)
{
- spin_lock_init(&dev_list_lock);
-
recv_sockets.sk4 = rxe_setup_udp_tunnel(&init_net,
htons(ROCE_V2_UDP_DPORT), false);
if (IS_ERR(recv_sockets.sk4)) {
@@ -676,8 +676,6 @@ int rxe_net_ipv6_init(void)
{
#if IS_ENABLED(CONFIG_IPV6)
- spin_lock_init(&dev_list_lock);
-
recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net,
htons(ROCE_V2_UDP_DPORT), true);
if (IS_ERR(recv_sockets.sk6)) {
diff --git a/drivers/infiniband/sw/rxe/rxe_param.h b/drivers/infiniband/sw/rxe/rxe_param.h
index f459c43a77c8..13ed2cc6eaa2 100644
--- a/drivers/infiniband/sw/rxe/rxe_param.h
+++ b/drivers/infiniband/sw/rxe/rxe_param.h
@@ -82,7 +82,7 @@ enum rxe_device_param {
RXE_MAX_SGE = 32,
RXE_MAX_SGE_RD = 32,
RXE_MAX_CQ = 16384,
- RXE_MAX_LOG_CQE = 13,
+ RXE_MAX_LOG_CQE = 15,
RXE_MAX_MR = 2 * 1024,
RXE_MAX_PD = 0x7ffc,
RXE_MAX_QP_RD_ATOM = 128,
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
index 6bac0717c540..d723947a8542 100644
--- a/drivers/infiniband/sw/rxe/rxe_pool.c
+++ b/drivers/infiniband/sw/rxe/rxe_pool.c
@@ -180,7 +180,6 @@ static int rxe_pool_init_index(struct rxe_pool *pool, u32 max, u32 min)
size = BITS_TO_LONGS(max - min + 1) * sizeof(long);
pool->table = kmalloc(size, GFP_KERNEL);
if (!pool->table) {
- pr_warn("no memory for bit table\n");
err = -ENOMEM;
goto out;
}
diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c
index 46f062842a9a..252b4d637d45 100644
--- a/drivers/infiniband/sw/rxe/rxe_recv.c
+++ b/drivers/infiniband/sw/rxe/rxe_recv.c
@@ -391,16 +391,15 @@ int rxe_rcv(struct sk_buff *skb)
payload_size(pkt));
calc_icrc = cpu_to_be32(~calc_icrc);
if (unlikely(calc_icrc != pack_icrc)) {
- char saddr[sizeof(struct in6_addr)];
-
if (skb->protocol == htons(ETH_P_IPV6))
- sprintf(saddr, "%pI6", &ipv6_hdr(skb)->saddr);
+ pr_warn_ratelimited("bad ICRC from %pI6c\n",
+ &ipv6_hdr(skb)->saddr);
else if (skb->protocol == htons(ETH_P_IP))
- sprintf(saddr, "%pI4", &ip_hdr(skb)->saddr);
+ pr_warn_ratelimited("bad ICRC from %pI4\n",
+ &ip_hdr(skb)->saddr);
else
- sprintf(saddr, "unknown");
+ pr_warn_ratelimited("bad ICRC from unknown\n");
- pr_warn_ratelimited("bad ICRC from %s\n", saddr);
goto drop;
}
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
index 22bd9630dcd9..73d4a97603a1 100644
--- a/drivers/infiniband/sw/rxe/rxe_req.c
+++ b/drivers/infiniband/sw/rxe/rxe_req.c
@@ -548,23 +548,23 @@ static void update_wqe_psn(struct rxe_qp *qp,
static void save_state(struct rxe_send_wqe *wqe,
struct rxe_qp *qp,
struct rxe_send_wqe *rollback_wqe,
- struct rxe_qp *rollback_qp)
+ u32 *rollback_psn)
{
rollback_wqe->state = wqe->state;
rollback_wqe->first_psn = wqe->first_psn;
rollback_wqe->last_psn = wqe->last_psn;
- rollback_qp->req.psn = qp->req.psn;
+ *rollback_psn = qp->req.psn;
}
static void rollback_state(struct rxe_send_wqe *wqe,
struct rxe_qp *qp,
struct rxe_send_wqe *rollback_wqe,
- struct rxe_qp *rollback_qp)
+ u32 rollback_psn)
{
wqe->state = rollback_wqe->state;
wqe->first_psn = rollback_wqe->first_psn;
wqe->last_psn = rollback_wqe->last_psn;
- qp->req.psn = rollback_qp->req.psn;
+ qp->req.psn = rollback_psn;
}
static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
@@ -593,8 +593,10 @@ int rxe_requester(void *arg)
int mtu;
int opcode;
int ret;
- struct rxe_qp rollback_qp;
struct rxe_send_wqe rollback_wqe;
+ u32 rollback_psn;
+
+ rxe_add_ref(qp);
next_wqe:
if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR))
@@ -697,6 +699,7 @@ next_wqe:
wqe->state = wqe_state_done;
wqe->status = IB_WC_SUCCESS;
__rxe_do_task(&qp->comp.task);
+ rxe_drop_ref(qp);
return 0;
}
payload = mtu;
@@ -719,7 +722,7 @@ next_wqe:
* rxe_xmit_packet().
* Otherwise, completer might initiate an unjustified retry flow.
*/
- save_state(wqe, qp, &rollback_wqe, &rollback_qp);
+ save_state(wqe, qp, &rollback_wqe, &rollback_psn);
update_wqe_state(qp, wqe, &pkt);
update_wqe_psn(qp, wqe, &pkt, payload);
ret = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, &pkt, skb);
@@ -727,7 +730,7 @@ next_wqe:
qp->need_req_skb = 1;
kfree_skb(skb);
- rollback_state(wqe, qp, &rollback_wqe, &rollback_qp);
+ rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
if (ret == -EAGAIN) {
rxe_run_task(&qp->req.task, 1);
@@ -756,8 +759,7 @@ err:
*/
wqe->wr.send_flags |= IB_SEND_SIGNALED;
__rxe_do_task(&qp->comp.task);
- return -EAGAIN;
-
exit:
+ rxe_drop_ref(qp);
return -EAGAIN;
}
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index dd3d88adc003..7a36ec9dbc0c 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -444,6 +444,13 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
return RESPST_EXECUTE;
}
+ /* A zero-byte op is not required to set an addr or rkey. */
+ if ((pkt->mask & (RXE_READ_MASK | RXE_WRITE_OR_SEND)) &&
+ (pkt->mask & RXE_RETH_MASK) &&
+ reth_len(pkt) == 0) {
+ return RESPST_EXECUTE;
+ }
+
va = qp->resp.va;
rkey = qp->resp.rkey;
resid = qp->resp.resid;
@@ -680,9 +687,14 @@ static enum resp_states read_reply(struct rxe_qp *qp,
res->read.va_org = qp->resp.va;
res->first_psn = req_pkt->psn;
- res->last_psn = req_pkt->psn +
- (reth_len(req_pkt) + mtu - 1) /
- mtu - 1;
+
+ if (reth_len(req_pkt)) {
+ res->last_psn = (req_pkt->psn +
+ (reth_len(req_pkt) + mtu - 1) /
+ mtu - 1) & BTH_PSN_MASK;
+ } else {
+ res->last_psn = res->first_psn;
+ }
res->cur_psn = req_pkt->psn;
res->read.resid = qp->resp.resid;
@@ -742,7 +754,8 @@ static enum resp_states read_reply(struct rxe_qp *qp,
} else {
qp->resp.res = NULL;
qp->resp.opcode = -1;
- qp->resp.psn = res->cur_psn;
+ if (psn_compare(res->cur_psn, qp->resp.psn) >= 0)
+ qp->resp.psn = res->cur_psn;
state = RESPST_CLEANUP;
}
@@ -1132,6 +1145,7 @@ static enum resp_states duplicate_request(struct rxe_qp *qp,
pkt, skb_copy);
if (rc) {
pr_err("Failed resending result. This flow is not handled - skb ignored\n");
+ rxe_drop_ref(qp);
kfree_skb(skb_copy);
rc = RESPST_CLEANUP;
goto out;
@@ -1198,6 +1212,8 @@ int rxe_responder(void *arg)
struct rxe_pkt_info *pkt = NULL;
int ret = 0;
+ rxe_add_ref(qp);
+
qp->resp.aeth_syndrome = AETH_ACK_UNLIMITED;
if (!qp->valid) {
@@ -1386,5 +1402,6 @@ int rxe_responder(void *arg)
exit:
ret = -EAGAIN;
done:
+ rxe_drop_ref(qp);
return ret;
}
diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c
index 2a6e3cd2d4e8..efc832a2d7c6 100644
--- a/drivers/infiniband/sw/rxe/rxe_srq.c
+++ b/drivers/infiniband/sw/rxe/rxe_srq.c
@@ -169,7 +169,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
}
}
- err = rxe_queue_resize(q, (unsigned int *)&attr->max_wr,
+ err = rxe_queue_resize(q, &attr->max_wr,
rcv_wqe_size(srq->rq.max_sge),
srq->rq.queue->ip ?
srq->rq.queue->ip->context :
diff --git a/drivers/infiniband/sw/rxe/rxe_task.c b/drivers/infiniband/sw/rxe/rxe_task.c
index 1e19bf828a6e..d2a14a1bdc7f 100644
--- a/drivers/infiniband/sw/rxe/rxe_task.c
+++ b/drivers/infiniband/sw/rxe/rxe_task.c
@@ -121,6 +121,7 @@ int rxe_init_task(void *obj, struct rxe_task *task,
task->arg = arg;
task->func = func;
snprintf(task->name, sizeof(task->name), "%s", name);
+ task->destroyed = false;
tasklet_init(&task->tasklet, rxe_do_task, (unsigned long)task);
@@ -132,11 +133,29 @@ int rxe_init_task(void *obj, struct rxe_task *task,
void rxe_cleanup_task(struct rxe_task *task)
{
+ unsigned long flags;
+ bool idle;
+
+ /*
+ * Mark the task, then wait for it to finish. It might be
+ * running in a non-tasklet (direct call) context.
+ */
+ task->destroyed = true;
+
+ do {
+ spin_lock_irqsave(&task->state_lock, flags);
+ idle = (task->state == TASK_STATE_START);
+ spin_unlock_irqrestore(&task->state_lock, flags);
+ } while (!idle);
+
tasklet_kill(&task->tasklet);
}
void rxe_run_task(struct rxe_task *task, int sched)
{
+ if (task->destroyed)
+ return;
+
if (sched)
tasklet_schedule(&task->tasklet);
else
diff --git a/drivers/infiniband/sw/rxe/rxe_task.h b/drivers/infiniband/sw/rxe/rxe_task.h
index d14aa6daed05..08ff42d451c6 100644
--- a/drivers/infiniband/sw/rxe/rxe_task.h
+++ b/drivers/infiniband/sw/rxe/rxe_task.h
@@ -54,6 +54,7 @@ struct rxe_task {
int (*func)(void *arg);
int ret;
char name[16];
+ bool destroyed;
};
/*
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 19841c863daf..beb7021ff18a 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -316,7 +316,9 @@ static int rxe_init_av(struct rxe_dev *rxe, struct ib_ah_attr *attr,
return err;
}
-static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
+static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr,
+ struct ib_udata *udata)
+
{
int err;
struct rxe_dev *rxe = to_rdev(ibpd->device);
@@ -564,7 +566,7 @@ static struct ib_qp *rxe_create_qp(struct ib_pd *ibpd,
if (udata) {
if (udata->inlen) {
err = -EINVAL;
- goto err1;
+ goto err2;
}
qp->is_user = 1;
}
@@ -573,12 +575,13 @@ static struct ib_qp *rxe_create_qp(struct ib_pd *ibpd,
err = rxe_qp_from_init(rxe, qp, pd, init, udata, ibpd);
if (err)
- goto err2;
+ goto err3;
return &qp->ibqp;
-err2:
+err3:
rxe_drop_index(qp);
+err2:
rxe_drop_ref(qp);
err1:
return ERR_PTR(err);
@@ -1007,11 +1010,19 @@ static int rxe_peek_cq(struct ib_cq *ibcq, int wc_cnt)
static int rxe_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
{
struct rxe_cq *cq = to_rcq(ibcq);
+ unsigned long irq_flags;
+ int ret = 0;
+ spin_lock_irqsave(&cq->cq_lock, irq_flags);
if (cq->notify != IB_CQ_NEXT_COMP)
cq->notify = flags & IB_CQ_SOLICITED_MASK;
- return 0;
+ if ((flags & IB_CQ_REPORT_MISSED_EVENTS) && !queue_empty(cq->queue))
+ ret = 1;
+
+ spin_unlock_irqrestore(&cq->cq_lock, irq_flags);
+
+ return ret;
}
static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 339a1eecdfe3..096c4f6fbd65 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -357,11 +357,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i
int i;
rx->rx_ring = vzalloc(ipoib_recvq_size * sizeof *rx->rx_ring);
- if (!rx->rx_ring) {
- printk(KERN_WARNING "%s: failed to allocate CM non-SRQ ring (%d entries)\n",
- priv->ca->name, ipoib_recvq_size);
+ if (!rx->rx_ring)
return -ENOMEM;
- }
t = kmalloc(sizeof *t, GFP_KERNEL);
if (!t) {
@@ -1054,8 +1051,6 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
tx_qp = ib_create_qp(priv->pd, &attr);
if (PTR_ERR(tx_qp) == -EINVAL) {
- ipoib_warn(priv, "can't use GFP_NOIO for QPs on device %s, using GFP_KERNEL\n",
- priv->ca->name);
attr.create_flags &= ~IB_QP_CREATE_USE_GFP_NOIO;
tx_qp = ib_create_qp(priv->pd, &attr);
}
@@ -1134,7 +1129,6 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
p->tx_ring = __vmalloc(ipoib_sendq_size * sizeof *p->tx_ring,
GFP_NOIO, PAGE_KERNEL);
if (!p->tx_ring) {
- ipoib_warn(priv, "failed to allocate tx ring\n");
ret = -ENOMEM;
goto err_tx;
}
@@ -1550,8 +1544,6 @@ static void ipoib_cm_create_srq(struct net_device *dev, int max_sge)
priv->cm.srq_ring = vzalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring);
if (!priv->cm.srq_ring) {
- printk(KERN_WARNING "%s: failed to allocate CM SRQ ring (%d entries)\n",
- priv->ca->name, ipoib_recvq_size);
ib_destroy_srq(priv->cm.srq);
priv->cm.srq = NULL;
return;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 830fecb6934c..5038f9d2d753 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -416,11 +416,8 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
"(status=%d, wrid=%d vend_err %x)\n",
wc->status, wr_id, wc->vendor_err);
qp_work = kzalloc(sizeof(*qp_work), GFP_ATOMIC);
- if (!qp_work) {
- ipoib_warn(priv, "%s Failed alloc ipoib_qp_state_validate for qp: 0x%x\n",
- __func__, priv->qp->qp_num);
+ if (!qp_work)
return;
- }
INIT_WORK(&qp_work->work, ipoib_qp_state_validate_work);
qp_work->priv = priv;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index c50794fb92db..3ce0765a05ab 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1619,11 +1619,8 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
/* Allocate RX/TX "rings" to hold queued skbs */
priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring,
GFP_KERNEL);
- if (!priv->rx_ring) {
- printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
- ca->name, ipoib_recvq_size);
+ if (!priv->rx_ring)
goto out;
- }
priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring);
if (!priv->tx_ring) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 1909dd252c94..fddff403d5d2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -575,8 +575,11 @@ void ipoib_mcast_join_task(struct work_struct *work)
if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
return;
- if (ib_query_port(priv->ca, priv->port, &port_attr) ||
- port_attr.state != IB_PORT_ACTIVE) {
+ if (ib_query_port(priv->ca, priv->port, &port_attr)) {
+ ipoib_dbg(priv, "ib_query_port() failed\n");
+ return;
+ }
+ if (port_attr.state != IB_PORT_ACTIVE) {
ipoib_dbg(priv, "port state is not ACTIVE (state = %d) suspending join task\n",
port_attr.state);
return;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index a4b791dfaa1d..8ae7a3beddb7 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -890,11 +890,14 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
case RDMA_CM_EVENT_ESTABLISHED:
iser_connected_handler(cma_id, event->param.conn.private_data);
break;
+ case RDMA_CM_EVENT_REJECTED:
+ iser_info("Connection rejected: %s\n",
+ rdma_reject_msg(cma_id, event->status));
+ /* FALLTHROUGH */
case RDMA_CM_EVENT_ADDR_ERROR:
case RDMA_CM_EVENT_ROUTE_ERROR:
case RDMA_CM_EVENT_CONNECT_ERROR:
case RDMA_CM_EVENT_UNREACHABLE:
- case RDMA_CM_EVENT_REJECTED:
iser_connect_error(cma_id);
break;
case RDMA_CM_EVENT_DISCONNECTED:
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 6dd43f63238e..314e95516068 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -184,7 +184,7 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
isert_conn->rx_descs = kzalloc(ISERT_QP_MAX_RECV_DTOS *
sizeof(struct iser_rx_desc), GFP_KERNEL);
if (!isert_conn->rx_descs)
- goto fail;
+ return -ENOMEM;
rx_desc = isert_conn->rx_descs;
@@ -213,9 +213,7 @@ dma_map_fail:
}
kfree(isert_conn->rx_descs);
isert_conn->rx_descs = NULL;
-fail:
isert_err("conn %p failed to allocate rx descriptors\n", isert_conn);
-
return -ENOMEM;
}
@@ -269,10 +267,8 @@ isert_alloc_comps(struct isert_device *device)
device->comps = kcalloc(device->comps_used, sizeof(struct isert_comp),
GFP_KERNEL);
- if (!device->comps) {
- isert_err("Unable to allocate completion contexts\n");
+ if (!device->comps)
return -ENOMEM;
- }
max_cqe = min(ISER_MAX_CQ_LEN, device->ib_device->attrs.max_cqe);
@@ -432,10 +428,8 @@ isert_alloc_login_buf(struct isert_conn *isert_conn,
isert_conn->login_req_buf = kzalloc(sizeof(*isert_conn->login_req_buf),
GFP_KERNEL);
- if (!isert_conn->login_req_buf) {
- isert_err("Unable to allocate isert_conn->login_buf\n");
+ if (!isert_conn->login_req_buf)
return -ENOMEM;
- }
isert_conn->login_req_dma = ib_dma_map_single(ib_dev,
isert_conn->login_req_buf,
@@ -795,6 +789,8 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
*/
return 1;
case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */
+ isert_info("Connection rejected: %s\n",
+ rdma_reject_msg(cma_id, event->status));
case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */
case RDMA_CM_EVENT_CONNECT_ERROR:
ret = isert_connect_error(cma_id);
@@ -1276,11 +1272,8 @@ isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd
if (payload_length) {
text_in = kzalloc(payload_length, GFP_KERNEL);
- if (!text_in) {
- isert_err("Unable to allocate text_in of payload_length: %u\n",
- payload_length);
+ if (!text_in)
return -ENOMEM;
- }
}
cmd->text_in_ptr = text_in;
@@ -1851,6 +1844,8 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
(void *)cmd->sense_buffer, pdu_len,
DMA_TO_DEVICE);
+ if (ib_dma_mapping_error(ib_dev, isert_cmd->pdu_buf_dma))
+ return -ENOMEM;
isert_cmd->pdu_buf_len = pdu_len;
tx_dsg->addr = isert_cmd->pdu_buf_dma;
@@ -1978,6 +1973,8 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
(void *)cmd->buf_ptr, ISCSI_HDR_LEN,
DMA_TO_DEVICE);
+ if (ib_dma_mapping_error(ib_dev, isert_cmd->pdu_buf_dma))
+ return -ENOMEM;
isert_cmd->pdu_buf_len = ISCSI_HDR_LEN;
tx_dsg->addr = isert_cmd->pdu_buf_dma;
tx_dsg->length = ISCSI_HDR_LEN;
@@ -2018,6 +2015,8 @@ isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
txt_rsp_buf, txt_rsp_len, DMA_TO_DEVICE);
+ if (ib_dma_mapping_error(ib_dev, isert_cmd->pdu_buf_dma))
+ return -ENOMEM;
isert_cmd->pdu_buf_len = txt_rsp_len;
tx_dsg->addr = isert_cmd->pdu_buf_dma;
@@ -2307,10 +2306,9 @@ isert_setup_np(struct iscsi_np *np,
int ret;
isert_np = kzalloc(sizeof(struct isert_np), GFP_KERNEL);
- if (!isert_np) {
- isert_err("Unable to allocate struct isert_np\n");
+ if (!isert_np)
return -ENOMEM;
- }
+
sema_init(&isert_np->sem, 0);
mutex_init(&isert_np->mutex);
INIT_LIST_HEAD(&isert_np->accepted);
@@ -2651,7 +2649,6 @@ static int __init isert_init(void)
WQ_UNBOUND | WQ_HIGHPRI, 0);
if (!isert_comp_wq) {
isert_err("Unable to allocate isert_comp_wq\n");
- ret = -ENOMEM;
return -ENOMEM;
}
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index d980fb458ad4..8ddc07123193 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -64,6 +64,11 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_INFO(release_date, DRV_RELDATE);
+#if !defined(CONFIG_DYNAMIC_DEBUG)
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)
+#define DYNAMIC_DEBUG_BRANCH(descriptor) false
+#endif
+
static unsigned int srp_sg_tablesize;
static unsigned int cmd_sg_entries;
static unsigned int indirect_sg_entries;
@@ -384,6 +389,9 @@ static struct srp_fr_pool *srp_create_fr_pool(struct ib_device *device,
max_page_list_len);
if (IS_ERR(mr)) {
ret = PTR_ERR(mr);
+ if (ret == -ENOMEM)
+ pr_info("%s: ib_alloc_mr() failed. Try to reduce max_cmd_per_lun, max_sect or ch_count\n",
+ dev_name(&device->dev));
goto destroy_pool;
}
d->mr = mr;
@@ -1266,8 +1274,12 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
struct ib_pool_fmr *fmr;
u64 io_addr = 0;
- if (state->fmr.next >= state->fmr.end)
+ if (state->fmr.next >= state->fmr.end) {
+ shost_printk(KERN_ERR, ch->target->scsi_host,
+ PFX "Out of MRs (mr_per_cmd = %d)\n",
+ ch->target->mr_per_cmd);
return -ENOMEM;
+ }
WARN_ON_ONCE(!dev->use_fmr);
@@ -1323,8 +1335,12 @@ static int srp_map_finish_fr(struct srp_map_state *state,
u32 rkey;
int n, err;
- if (state->fr.next >= state->fr.end)
+ if (state->fr.next >= state->fr.end) {
+ shost_printk(KERN_ERR, ch->target->scsi_host,
+ PFX "Out of MRs (mr_per_cmd = %d)\n",
+ ch->target->mr_per_cmd);
return -ENOMEM;
+ }
WARN_ON_ONCE(!dev->use_fast_reg);
@@ -1556,7 +1572,6 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,
return 0;
}
-#if defined(DYNAMIC_DATA_DEBUG)
static void srp_check_mapping(struct srp_map_state *state,
struct srp_rdma_ch *ch, struct srp_request *req,
struct scatterlist *scat, int count)
@@ -1580,7 +1595,6 @@ static void srp_check_mapping(struct srp_map_state *state,
scsi_bufflen(req->scmnd), desc_len, mr_len,
state->ndesc, state->nmdesc);
}
-#endif
/**
* srp_map_data() - map SCSI data buffer onto an SRP request
@@ -1669,14 +1683,12 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
if (ret < 0)
goto unmap;
-#if defined(DYNAMIC_DEBUG)
{
DEFINE_DYNAMIC_DEBUG_METADATA(ddm,
"Memory mapping consistency check");
- if (unlikely(ddm.flags & _DPRINTK_FLAGS_PRINT))
+ if (DYNAMIC_DEBUG_BRANCH(ddm))
srp_check_mapping(&state, ch, req, scat, count);
}
-#endif
/* We've mapped the request, now pull as much of the indirect
* descriptor table as we can into the command buffer. If this
@@ -3287,7 +3299,9 @@ static ssize_t srp_create_target(struct device *dev,
*/
scsi_host_get(target->scsi_host);
- mutex_lock(&host->add_target_mutex);
+ ret = mutex_lock_interruptible(&host->add_target_mutex);
+ if (ret < 0)
+ goto put;
ret = srp_parse_options(buf, target);
if (ret)
@@ -3443,6 +3457,7 @@ connected:
out:
mutex_unlock(&host->add_target_mutex);
+put:
scsi_host_put(target->scsi_host);
if (ret < 0)
scsi_host_put(target->scsi_host);
@@ -3526,6 +3541,7 @@ free_host:
static void srp_add_one(struct ib_device *device)
{
struct srp_device *srp_dev;
+ struct ib_device_attr *attr = &device->attrs;
struct srp_host *host;
int mr_page_shift, p;
u64 max_pages_per_mr;
@@ -3540,25 +3556,25 @@ 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(device->attrs.page_size_cap) - 1);
+ mr_page_shift = max(12, ffs(attr->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 = device->attrs.max_mr_size;
+ max_pages_per_mr = attr->max_mr_size;
do_div(max_pages_per_mr, srp_dev->mr_page_size);
pr_debug("%s: %llu / %u = %llu <> %u\n", __func__,
- device->attrs.max_mr_size, srp_dev->mr_page_size,
+ attr->max_mr_size, srp_dev->mr_page_size,
max_pages_per_mr, SRP_MAX_PAGES_PER_MR);
srp_dev->max_pages_per_mr = min_t(u64, SRP_MAX_PAGES_PER_MR,
max_pages_per_mr);
srp_dev->has_fmr = (device->alloc_fmr && device->dealloc_fmr &&
device->map_phys_fmr && device->unmap_fmr);
- srp_dev->has_fr = (device->attrs.device_cap_flags &
+ srp_dev->has_fr = (attr->device_cap_flags &
IB_DEVICE_MEM_MGT_EXTENSIONS);
if (!never_register && !srp_dev->has_fmr && !srp_dev->has_fr) {
dev_warn(&device->dev, "neither FMR nor FR is supported\n");
} else if (!never_register &&
- device->attrs.max_mr_size >= 2 * srp_dev->mr_page_size) {
+ attr->max_mr_size >= 2 * srp_dev->mr_page_size) {
srp_dev->use_fast_reg = (srp_dev->has_fr &&
(!srp_dev->has_fmr || prefer_fr));
srp_dev->use_fmr = !srp_dev->use_fast_reg && srp_dev->has_fmr;
@@ -3571,13 +3587,13 @@ static void srp_add_one(struct ib_device *device)
if (srp_dev->use_fast_reg) {
srp_dev->max_pages_per_mr =
min_t(u32, srp_dev->max_pages_per_mr,
- device->attrs.max_fast_reg_page_list_len);
+ attr->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, 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,
+ device->name, mr_page_shift, attr->max_mr_size,
+ attr->max_fast_reg_page_list_len,
srp_dev->max_pages_per_mr, srp_dev->mr_max_size);
INIT_LIST_HEAD(&srp_dev->dev_list);
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 0b1f69ed2e92..d21ba9d857c3 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1840,7 +1840,6 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
struct srpt_rdma_ch *ch, *tmp_ch;
u32 it_iu_len;
int i, ret = 0;
- unsigned char *p;
WARN_ON_ONCE(irqs_disabled());
@@ -1994,21 +1993,18 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
be64_to_cpu(*(__be64 *)(ch->i_port_id + 8)));
pr_debug("registering session %s\n", ch->sess_name);
- p = &ch->sess_name[0];
-try_again:
ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
- TARGET_PROT_NORMAL, p, ch, NULL);
+ TARGET_PROT_NORMAL, ch->sess_name, ch,
+ NULL);
+ /* Retry without leading "0x" */
+ if (IS_ERR(ch->sess))
+ ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
+ TARGET_PROT_NORMAL,
+ ch->sess_name + 2, ch, NULL);
if (IS_ERR(ch->sess)) {
- pr_info("Rejected login because no ACL has been"
- " configured yet for initiator %s.\n", p);
- /*
- * XXX: Hack to retry of ch->i_port_id without leading '0x'
- */
- if (p == &ch->sess_name[0]) {
- p += 2;
- goto try_again;
- }
+ pr_info("Rejected login because no ACL has been configured yet for initiator %s.\n",
+ ch->sess_name);
rej->reason = cpu_to_be32((PTR_ERR(ch->sess) == -ENOMEM) ?
SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES :
SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED);
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 754595ee11b6..019e02707cd5 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -373,6 +373,8 @@ static struct iommu_group *acpihid_device_group(struct device *dev)
if (!entry->group)
entry->group = generic_device_group(dev);
+ else
+ iommu_group_ref_get(entry->group);
return entry->group;
}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 157e93421fb8..971154cbbb03 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -28,6 +28,7 @@
#include <linux/amd-iommu.h>
#include <linux/export.h>
#include <linux/iommu.h>
+#include <linux/kmemleak.h>
#include <asm/pci-direct.h>
#include <asm/iommu.h>
#include <asm/gart.h>
@@ -2090,6 +2091,7 @@ static struct syscore_ops amd_iommu_syscore_ops = {
static void __init free_on_init_error(void)
{
+ kmemleak_free(irq_lookup_table);
free_pages((unsigned long)irq_lookup_table,
get_order(rlookup_table_size));
@@ -2321,6 +2323,8 @@ static int __init early_amd_iommu_init(void)
irq_lookup_table = (void *)__get_free_pages(
GFP_KERNEL | __GFP_ZERO,
get_order(rlookup_table_size));
+ kmemleak_alloc(irq_lookup_table, rlookup_table_size,
+ 1, GFP_KERNEL);
if (!irq_lookup_table)
goto out;
}
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index 594849a3a9be..f8ed8c95b685 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -805,8 +805,10 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
goto out_free_domain;
group = iommu_group_get(&pdev->dev);
- if (!group)
+ if (!group) {
+ ret = -EINVAL;
goto out_free_domain;
+ }
ret = iommu_attach_group(dev_state->domain, group);
if (ret != 0)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index e6f9b2d745ca..4d6ec444a9d6 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -20,6 +20,8 @@
* This driver is powered by bad coffee and bombay mix.
*/
+#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/delay.h>
#include <linux/dma-iommu.h>
#include <linux/err.h>
@@ -1358,7 +1360,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
} while (size -= granule);
}
-static struct iommu_gather_ops arm_smmu_gather_ops = {
+static const struct iommu_gather_ops arm_smmu_gather_ops = {
.tlb_flush_all = arm_smmu_tlb_inv_context,
.tlb_add_flush = arm_smmu_tlb_inv_range_nosync,
.tlb_sync = arm_smmu_tlb_sync,
@@ -1723,13 +1725,14 @@ static struct platform_driver arm_smmu_driver;
static int arm_smmu_match_node(struct device *dev, void *data)
{
- return dev->of_node == data;
+ return dev->fwnode == data;
}
-static struct arm_smmu_device *arm_smmu_get_by_node(struct device_node *np)
+static
+struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
{
struct device *dev = driver_find_device(&arm_smmu_driver.driver, NULL,
- np, arm_smmu_match_node);
+ fwnode, arm_smmu_match_node);
put_device(dev);
return dev ? dev_get_drvdata(dev) : NULL;
}
@@ -1765,7 +1768,7 @@ static int arm_smmu_add_device(struct device *dev)
master = fwspec->iommu_priv;
smmu = master->smmu;
} else {
- smmu = arm_smmu_get_by_node(to_of_node(fwspec->iommu_fwnode));
+ smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
if (!smmu)
return -ENODEV;
master = kzalloc(sizeof(*master), GFP_KERNEL);
@@ -2380,10 +2383,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
return 0;
}
-static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
+static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
{
u32 reg;
- bool coherent;
+ bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
/* IDR0 */
reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
@@ -2435,13 +2438,9 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
smmu->features |= ARM_SMMU_FEAT_HYP;
/*
- * The dma-coherent property is used in preference to the ID
+ * The coherency feature as set by FW is used in preference to the ID
* register, but warn on mismatch.
*/
- coherent = of_dma_is_coherent(smmu->dev->of_node);
- if (coherent)
- smmu->features |= ARM_SMMU_FEAT_COHERENCY;
-
if (!!(reg & IDR0_COHACC) != coherent)
dev_warn(smmu->dev, "IDR0.COHACC overridden by dma-coherent property (%s)\n",
coherent ? "true" : "false");
@@ -2562,21 +2561,61 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
return 0;
}
-static int arm_smmu_device_dt_probe(struct platform_device *pdev)
+#ifdef CONFIG_ACPI
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ struct acpi_iort_smmu_v3 *iort_smmu;
+ struct device *dev = smmu->dev;
+ struct acpi_iort_node *node;
+
+ node = *(struct acpi_iort_node **)dev_get_platdata(dev);
+
+ /* Retrieve SMMUv3 specific data */
+ iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+ if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
+ smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+ return 0;
+}
+#else
+static inline int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ return -ENODEV;
+}
+#endif
+
+static int arm_smmu_device_dt_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
{
- int irq, ret;
- struct resource *res;
- struct arm_smmu_device *smmu;
struct device *dev = &pdev->dev;
- bool bypass = true;
u32 cells;
+ int ret = -EINVAL;
if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells))
dev_err(dev, "missing #iommu-cells property\n");
else if (cells != 1)
dev_err(dev, "invalid #iommu-cells value (%d)\n", cells);
else
- bypass = false;
+ ret = 0;
+
+ parse_driver_options(smmu);
+
+ if (of_dma_is_coherent(dev->of_node))
+ smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+ return ret;
+}
+
+static int arm_smmu_device_probe(struct platform_device *pdev)
+{
+ int irq, ret;
+ struct resource *res;
+ struct arm_smmu_device *smmu;
+ struct device *dev = &pdev->dev;
+ bool bypass;
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
if (!smmu) {
@@ -2613,10 +2652,19 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
if (irq > 0)
smmu->gerr_irq = irq;
- parse_driver_options(smmu);
+ if (dev->of_node) {
+ ret = arm_smmu_device_dt_probe(pdev, smmu);
+ } else {
+ ret = arm_smmu_device_acpi_probe(pdev, smmu);
+ if (ret == -ENODEV)
+ return ret;
+ }
+
+ /* Set bypass mode according to firmware probing result */
+ bypass = !!ret;
/* Probe the h/w */
- ret = arm_smmu_device_probe(smmu);
+ ret = arm_smmu_device_hw_probe(smmu);
if (ret)
return ret;
@@ -2634,7 +2682,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
return ret;
/* And we're up. Go go go! */
- of_iommu_set_ops(dev->of_node, &arm_smmu_ops);
+ iommu_register_instance(dev->fwnode, &arm_smmu_ops);
+
#ifdef CONFIG_PCI
if (pci_bus_type.iommu_ops != &arm_smmu_ops) {
pci_request_acs();
@@ -2677,7 +2726,7 @@ static struct platform_driver arm_smmu_driver = {
.name = "arm-smmu-v3",
.of_match_table = of_match_ptr(arm_smmu_of_match),
},
- .probe = arm_smmu_device_dt_probe,
+ .probe = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
};
@@ -2715,6 +2764,17 @@ static int __init arm_smmu_of_init(struct device_node *np)
}
IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
+#ifdef CONFIG_ACPI
+static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
+{
+ if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
+ return arm_smmu_init();
+
+ return 0;
+}
+IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
+#endif
+
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 8f7281444551..a60cded8a6ed 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -28,6 +28,8 @@
#define pr_fmt(fmt) "arm-smmu: " fmt
+#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/dma-iommu.h>
@@ -247,6 +249,7 @@ enum arm_smmu_s2cr_privcfg {
#define ARM_MMU500_ACTLR_CPRE (1 << 1)
#define ARM_MMU500_ACR_CACHE_LOCK (1 << 26)
+#define ARM_MMU500_ACR_SMTNMB_TLBEN (1 << 8)
#define CB_PAR_F (1 << 0)
@@ -642,7 +645,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
}
}
-static struct iommu_gather_ops arm_smmu_gather_ops = {
+static const struct iommu_gather_ops arm_smmu_gather_ops = {
.tlb_flush_all = arm_smmu_tlb_inv_context,
.tlb_add_flush = arm_smmu_tlb_inv_range_nosync,
.tlb_sync = arm_smmu_tlb_sync,
@@ -1379,13 +1382,14 @@ static bool arm_smmu_capable(enum iommu_cap cap)
static int arm_smmu_match_node(struct device *dev, void *data)
{
- return dev->of_node == data;
+ return dev->fwnode == data;
}
-static struct arm_smmu_device *arm_smmu_get_by_node(struct device_node *np)
+static
+struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
{
struct device *dev = driver_find_device(&arm_smmu_driver.driver, NULL,
- np, arm_smmu_match_node);
+ fwnode, arm_smmu_match_node);
put_device(dev);
return dev ? dev_get_drvdata(dev) : NULL;
}
@@ -1403,7 +1407,7 @@ static int arm_smmu_add_device(struct device *dev)
if (ret)
goto out_free;
} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
- smmu = arm_smmu_get_by_node(to_of_node(fwspec->iommu_fwnode));
+ smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
} else {
return -ENODEV;
}
@@ -1478,7 +1482,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
}
if (group)
- return group;
+ return iommu_group_ref_get(group);
if (dev_is_pci(dev))
group = pci_device_group(dev);
@@ -1581,16 +1585,22 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
for (i = 0; i < smmu->num_mapping_groups; ++i)
arm_smmu_write_sme(smmu, i);
- /*
- * Before clearing ARM_MMU500_ACTLR_CPRE, need to
- * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
- * bit is only present in MMU-500r2 onwards.
- */
- reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
- major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
- if ((smmu->model == ARM_MMU500) && (major >= 2)) {
+ if (smmu->model == ARM_MMU500) {
+ /*
+ * Before clearing ARM_MMU500_ACTLR_CPRE, need to
+ * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
+ * bit is only present in MMU-500r2 onwards.
+ */
+ reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
+ major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
- reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+ if (major >= 2)
+ reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+ /*
+ * Allow unmatched Stream IDs to allocate bypass
+ * TLB entries for reduced latency.
+ */
+ reg |= ARM_MMU500_ACR_SMTNMB_TLBEN;
writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
}
@@ -1667,7 +1677,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
unsigned long size;
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
u32 id;
- bool cttw_dt, cttw_reg;
+ bool cttw_reg, cttw_fw = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK;
int i;
dev_notice(smmu->dev, "probing hardware configuration...\n");
@@ -1712,20 +1722,17 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
/*
* In order for DMA API calls to work properly, we must defer to what
- * the DT says about coherency, regardless of what the hardware claims.
+ * the FW says about coherency, regardless of what the hardware claims.
* Fortunately, this also opens up a workaround for systems where the
* ID register value has ended up configured incorrectly.
*/
- cttw_dt = of_dma_is_coherent(smmu->dev->of_node);
cttw_reg = !!(id & ID0_CTTW);
- if (cttw_dt)
- smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
- if (cttw_dt || cttw_reg)
+ if (cttw_fw || cttw_reg)
dev_notice(smmu->dev, "\t%scoherent table walk\n",
- cttw_dt ? "" : "non-");
- if (cttw_dt != cttw_reg)
+ cttw_fw ? "" : "non-");
+ if (cttw_fw != cttw_reg)
dev_notice(smmu->dev,
- "\t(IDR0.CTTW overridden by dma-coherent property)\n");
+ "\t(IDR0.CTTW overridden by FW configuration)\n");
/* Max. number of entries we have for stream matching/indexing */
size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK);
@@ -1906,15 +1913,83 @@ static const struct of_device_id arm_smmu_of_match[] = {
};
MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
-static int arm_smmu_device_dt_probe(struct platform_device *pdev)
+#ifdef CONFIG_ACPI
+static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
+{
+ int ret = 0;
+
+ switch (model) {
+ case ACPI_IORT_SMMU_V1:
+ case ACPI_IORT_SMMU_CORELINK_MMU400:
+ smmu->version = ARM_SMMU_V1;
+ smmu->model = GENERIC_SMMU;
+ break;
+ case ACPI_IORT_SMMU_V2:
+ smmu->version = ARM_SMMU_V2;
+ smmu->model = GENERIC_SMMU;
+ break;
+ case ACPI_IORT_SMMU_CORELINK_MMU500:
+ smmu->version = ARM_SMMU_V2;
+ smmu->model = ARM_MMU500;
+ break;
+ default:
+ ret = -ENODEV;
+ }
+
+ return ret;
+}
+
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ struct device *dev = smmu->dev;
+ struct acpi_iort_node *node =
+ *(struct acpi_iort_node **)dev_get_platdata(dev);
+ struct acpi_iort_smmu *iort_smmu;
+ int ret;
+
+ /* Retrieve SMMU1/2 specific data */
+ iort_smmu = (struct acpi_iort_smmu *)node->node_data;
+
+ ret = acpi_smmu_get_data(iort_smmu->model, smmu);
+ if (ret < 0)
+ return ret;
+
+ /* Ignore the configuration access interrupt */
+ smmu->num_global_irqs = 1;
+
+ if (iort_smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK)
+ smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
+
+ return 0;
+}
+#else
+static inline int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
+{
+ return -ENODEV;
+}
+#endif
+
+static int arm_smmu_device_dt_probe(struct platform_device *pdev,
+ struct arm_smmu_device *smmu)
{
const struct arm_smmu_match_data *data;
- struct resource *res;
- struct arm_smmu_device *smmu;
struct device *dev = &pdev->dev;
- int num_irqs, i, err;
bool legacy_binding;
+ if (of_property_read_u32(dev->of_node, "#global-interrupts",
+ &smmu->num_global_irqs)) {
+ dev_err(dev, "missing #global-interrupts property\n");
+ return -ENODEV;
+ }
+
+ data = of_device_get_match_data(dev);
+ smmu->version = data->version;
+ smmu->model = data->model;
+
+ parse_driver_options(smmu);
+
legacy_binding = of_find_property(dev->of_node, "mmu-masters", NULL);
if (legacy_binding && !using_generic_binding) {
if (!using_legacy_binding)
@@ -1927,6 +2002,19 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
return -ENODEV;
}
+ if (of_dma_is_coherent(dev->of_node))
+ smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
+
+ return 0;
+}
+
+static int arm_smmu_device_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct arm_smmu_device *smmu;
+ struct device *dev = &pdev->dev;
+ int num_irqs, i, err;
+
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
if (!smmu) {
dev_err(dev, "failed to allocate arm_smmu_device\n");
@@ -1934,9 +2022,13 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
}
smmu->dev = dev;
- data = of_device_get_match_data(dev);
- smmu->version = data->version;
- smmu->model = data->model;
+ if (dev->of_node)
+ err = arm_smmu_device_dt_probe(pdev, smmu);
+ else
+ err = arm_smmu_device_acpi_probe(pdev, smmu);
+
+ if (err)
+ return err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
smmu->base = devm_ioremap_resource(dev, res);
@@ -1944,12 +2036,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
return PTR_ERR(smmu->base);
smmu->size = resource_size(res);
- if (of_property_read_u32(dev->of_node, "#global-interrupts",
- &smmu->num_global_irqs)) {
- dev_err(dev, "missing #global-interrupts property\n");
- return -ENODEV;
- }
-
num_irqs = 0;
while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) {
num_irqs++;
@@ -1984,8 +2070,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
if (err)
return err;
- parse_driver_options(smmu);
-
if (smmu->version == ARM_SMMU_V2 &&
smmu->num_context_banks != smmu->num_context_irqs) {
dev_err(dev,
@@ -2007,7 +2091,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
}
}
- of_iommu_set_ops(dev->of_node, &arm_smmu_ops);
+ iommu_register_instance(dev->fwnode, &arm_smmu_ops);
platform_set_drvdata(pdev, smmu);
arm_smmu_device_reset(smmu);
@@ -2047,7 +2131,7 @@ static struct platform_driver arm_smmu_driver = {
.name = "arm-smmu",
.of_match_table = of_match_ptr(arm_smmu_of_match),
},
- .probe = arm_smmu_device_dt_probe,
+ .probe = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
};
@@ -2090,6 +2174,17 @@ IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", arm_smmu_of_init);
IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", arm_smmu_of_init);
IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", arm_smmu_of_init);
+#ifdef CONFIG_ACPI
+static int __init arm_smmu_acpi_init(struct acpi_table_header *table)
+{
+ if (iort_node_match(ACPI_IORT_NODE_SMMU))
+ return arm_smmu_init();
+
+ return 0;
+}
+IORT_ACPI_DECLARE(arm_smmu, ACPI_SIG_IORT, arm_smmu_acpi_init);
+#endif
+
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index c5ab8667e6f2..2db0d641cf45 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -432,13 +432,12 @@ int iommu_dma_mmap(struct page **pages, size_t size, struct vm_area_struct *vma)
return ret;
}
-dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, int prot)
+static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,
+ size_t size, int prot)
{
dma_addr_t dma_addr;
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
struct iova_domain *iovad = cookie_iovad(domain);
- phys_addr_t phys = page_to_phys(page) + offset;
size_t iova_off = iova_offset(iovad, phys);
size_t len = iova_align(iovad, size + iova_off);
struct iova *iova = __alloc_iova(domain, len, dma_get_mask(dev));
@@ -454,6 +453,12 @@ dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
return dma_addr + iova_off;
}
+dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, int prot)
+{
+ return __iommu_dma_map(dev, page_to_phys(page) + offset, size, prot);
+}
+
void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir, unsigned long attrs)
{
@@ -624,6 +629,19 @@ void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
__iommu_dma_unmap(iommu_get_domain_for_dev(dev), sg_dma_address(sg));
}
+dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys,
+ size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+ return __iommu_dma_map(dev, phys, size,
+ dma_direction_to_prot(dir, false) | IOMMU_MMIO);
+}
+
+void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+ __iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);
+}
+
int iommu_dma_supported(struct device *dev, u64 mask)
{
/*
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 30808e91b775..57ba0d3091ea 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -70,6 +70,36 @@ static short PG_ENT_SHIFT = -1;
#define SYSMMU_PG_ENT_SHIFT 0
#define SYSMMU_V5_PG_ENT_SHIFT 4
+static const sysmmu_pte_t *LV1_PROT;
+static const sysmmu_pte_t SYSMMU_LV1_PROT[] = {
+ ((0 << 15) | (0 << 10)), /* no access */
+ ((1 << 15) | (1 << 10)), /* IOMMU_READ only */
+ ((0 << 15) | (1 << 10)), /* IOMMU_WRITE not supported, use read/write */
+ ((0 << 15) | (1 << 10)), /* IOMMU_READ | IOMMU_WRITE */
+};
+static const sysmmu_pte_t SYSMMU_V5_LV1_PROT[] = {
+ (0 << 4), /* no access */
+ (1 << 4), /* IOMMU_READ only */
+ (2 << 4), /* IOMMU_WRITE only */
+ (3 << 4), /* IOMMU_READ | IOMMU_WRITE */
+};
+
+static const sysmmu_pte_t *LV2_PROT;
+static const sysmmu_pte_t SYSMMU_LV2_PROT[] = {
+ ((0 << 9) | (0 << 4)), /* no access */
+ ((1 << 9) | (1 << 4)), /* IOMMU_READ only */
+ ((0 << 9) | (1 << 4)), /* IOMMU_WRITE not supported, use read/write */
+ ((0 << 9) | (1 << 4)), /* IOMMU_READ | IOMMU_WRITE */
+};
+static const sysmmu_pte_t SYSMMU_V5_LV2_PROT[] = {
+ (0 << 2), /* no access */
+ (1 << 2), /* IOMMU_READ only */
+ (2 << 2), /* IOMMU_WRITE only */
+ (3 << 2), /* IOMMU_READ | IOMMU_WRITE */
+};
+
+#define SYSMMU_SUPPORTED_PROT_BITS (IOMMU_READ | IOMMU_WRITE)
+
#define sect_to_phys(ent) (((phys_addr_t) ent) << PG_ENT_SHIFT)
#define section_phys(sent) (sect_to_phys(*(sent)) & SECT_MASK)
#define section_offs(iova) (iova & (SECT_SIZE - 1))
@@ -97,16 +127,17 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
#define SPAGES_PER_LPAGE (LPAGE_SIZE / SPAGE_SIZE)
#define lv2table_base(sent) (sect_to_phys(*(sent) & 0xFFFFFFC0))
-#define mk_lv1ent_sect(pa) ((pa >> PG_ENT_SHIFT) | 2)
+#define mk_lv1ent_sect(pa, prot) ((pa >> PG_ENT_SHIFT) | LV1_PROT[prot] | 2)
#define mk_lv1ent_page(pa) ((pa >> PG_ENT_SHIFT) | 1)
-#define mk_lv2ent_lpage(pa) ((pa >> PG_ENT_SHIFT) | 1)
-#define mk_lv2ent_spage(pa) ((pa >> PG_ENT_SHIFT) | 2)
+#define mk_lv2ent_lpage(pa, prot) ((pa >> PG_ENT_SHIFT) | LV2_PROT[prot] | 1)
+#define mk_lv2ent_spage(pa, prot) ((pa >> PG_ENT_SHIFT) | LV2_PROT[prot] | 2)
#define CTRL_ENABLE 0x5
#define CTRL_BLOCK 0x7
#define CTRL_DISABLE 0x0
#define CFG_LRU 0x1
+#define CFG_EAP (1 << 2)
#define CFG_QOS(n) ((n & 0xF) << 7)
#define CFG_ACGEN (1 << 24) /* System MMU 3.3 only */
#define CFG_SYSSEL (1 << 22) /* System MMU 3.2 only */
@@ -206,6 +237,7 @@ static const struct sysmmu_fault_info sysmmu_v5_faults[] = {
struct exynos_iommu_owner {
struct list_head controllers; /* list of sysmmu_drvdata.owner_node */
struct iommu_domain *domain; /* domain this device is attached */
+ struct mutex rpm_lock; /* for runtime pm of all sysmmus */
};
/*
@@ -237,8 +269,8 @@ struct sysmmu_drvdata {
struct clk *aclk; /* SYSMMU's aclk clock */
struct clk *pclk; /* SYSMMU's pclk clock */
struct clk *clk_master; /* master's device clock */
- int activations; /* number of calls to sysmmu_enable */
spinlock_t lock; /* lock for modyfying state */
+ bool active; /* current status */
struct exynos_iommu_domain *domain; /* domain we belong to */
struct list_head domain_node; /* node for domain clients list */
struct list_head owner_node; /* node for owner controllers list */
@@ -251,25 +283,6 @@ static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
return container_of(dom, struct exynos_iommu_domain, domain);
}
-static bool set_sysmmu_active(struct sysmmu_drvdata *data)
-{
- /* return true if the System MMU was not active previously
- and it needs to be initialized */
- return ++data->activations == 1;
-}
-
-static bool set_sysmmu_inactive(struct sysmmu_drvdata *data)
-{
- /* return true if the System MMU is needed to be disabled */
- BUG_ON(data->activations < 1);
- return --data->activations == 0;
-}
-
-static bool is_sysmmu_active(struct sysmmu_drvdata *data)
-{
- return data->activations > 0;
-}
-
static void sysmmu_unblock(struct sysmmu_drvdata *data)
{
writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
@@ -388,7 +401,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
unsigned short reg_status, reg_clear;
int ret = -ENOSYS;
- WARN_ON(!is_sysmmu_active(data));
+ WARN_ON(!data->active);
if (MMU_MAJ_VER(data->version) < 5) {
reg_status = REG_INT_STATUS;
@@ -434,40 +447,19 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void __sysmmu_disable_nocount(struct sysmmu_drvdata *data)
+static void __sysmmu_disable(struct sysmmu_drvdata *data)
{
+ unsigned long flags;
+
clk_enable(data->clk_master);
+ spin_lock_irqsave(&data->lock, flags);
writel(CTRL_DISABLE, data->sfrbase + REG_MMU_CTRL);
writel(0, data->sfrbase + REG_MMU_CFG);
-
- __sysmmu_disable_clocks(data);
-}
-
-static bool __sysmmu_disable(struct sysmmu_drvdata *data)
-{
- bool disabled;
- unsigned long flags;
-
- spin_lock_irqsave(&data->lock, flags);
-
- disabled = set_sysmmu_inactive(data);
-
- if (disabled) {
- data->pgtable = 0;
- data->domain = NULL;
-
- __sysmmu_disable_nocount(data);
-
- dev_dbg(data->sysmmu, "Disabled\n");
- } else {
- dev_dbg(data->sysmmu, "%d times left to disable\n",
- data->activations);
- }
-
+ data->active = false;
spin_unlock_irqrestore(&data->lock, flags);
- return disabled;
+ __sysmmu_disable_clocks(data);
}
static void __sysmmu_init_config(struct sysmmu_drvdata *data)
@@ -481,20 +473,24 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
else
cfg = CFG_QOS(15) | CFG_FLPDCACHE | CFG_ACGEN;
+ cfg |= CFG_EAP; /* enable access protection bits check */
+
writel(cfg, data->sfrbase + REG_MMU_CFG);
}
-static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
+static void __sysmmu_enable(struct sysmmu_drvdata *data)
{
+ unsigned long flags;
+
__sysmmu_enable_clocks(data);
+ spin_lock_irqsave(&data->lock, flags);
writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL);
-
__sysmmu_init_config(data);
-
__sysmmu_set_ptbase(data, data->pgtable);
-
writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
+ data->active = true;
+ spin_unlock_irqrestore(&data->lock, flags);
/*
* SYSMMU driver keeps master's clock enabled only for the short
@@ -505,48 +501,18 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
clk_disable(data->clk_master);
}
-static int __sysmmu_enable(struct sysmmu_drvdata *data, phys_addr_t pgtable,
- struct exynos_iommu_domain *domain)
-{
- int ret = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&data->lock, flags);
- if (set_sysmmu_active(data)) {
- data->pgtable = pgtable;
- data->domain = domain;
-
- __sysmmu_enable_nocount(data);
-
- dev_dbg(data->sysmmu, "Enabled\n");
- } else {
- ret = (pgtable == data->pgtable) ? 1 : -EBUSY;
-
- dev_dbg(data->sysmmu, "already enabled\n");
- }
-
- if (WARN_ON(ret < 0))
- set_sysmmu_inactive(data); /* decrement count */
-
- spin_unlock_irqrestore(&data->lock, flags);
-
- return ret;
-}
-
static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
sysmmu_iova_t iova)
{
unsigned long flags;
-
spin_lock_irqsave(&data->lock, flags);
- if (is_sysmmu_active(data) && data->version >= MAKE_MMU_VER(3, 3)) {
+ if (data->active && data->version >= MAKE_MMU_VER(3, 3)) {
clk_enable(data->clk_master);
__sysmmu_tlb_invalidate_entry(data, iova, 1);
clk_disable(data->clk_master);
}
spin_unlock_irqrestore(&data->lock, flags);
-
}
static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
@@ -555,7 +521,7 @@ static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
unsigned long flags;
spin_lock_irqsave(&data->lock, flags);
- if (is_sysmmu_active(data)) {
+ if (data->active) {
unsigned int num_inv = 1;
clk_enable(data->clk_master);
@@ -578,9 +544,6 @@ static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
sysmmu_unblock(data);
}
clk_disable(data->clk_master);
- } else {
- dev_dbg(data->master,
- "disabled. Skipping TLB invalidation @ %#x\n", iova);
}
spin_unlock_irqrestore(&data->lock, flags);
}
@@ -652,10 +615,15 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
__sysmmu_get_version(data);
if (PG_ENT_SHIFT < 0) {
- if (MMU_MAJ_VER(data->version) < 5)
+ if (MMU_MAJ_VER(data->version) < 5) {
PG_ENT_SHIFT = SYSMMU_PG_ENT_SHIFT;
- else
+ LV1_PROT = SYSMMU_LV1_PROT;
+ LV2_PROT = SYSMMU_LV2_PROT;
+ } else {
PG_ENT_SHIFT = SYSMMU_V5_PG_ENT_SHIFT;
+ LV1_PROT = SYSMMU_V5_LV1_PROT;
+ LV2_PROT = SYSMMU_V5_LV2_PROT;
+ }
}
pm_runtime_enable(dev);
@@ -665,34 +633,46 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
-static int exynos_sysmmu_suspend(struct device *dev)
+static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
{
struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+ struct device *master = data->master;
+
+ if (master) {
+ struct exynos_iommu_owner *owner = master->archdata.iommu;
- dev_dbg(dev, "suspend\n");
- if (is_sysmmu_active(data)) {
- __sysmmu_disable_nocount(data);
- pm_runtime_put(dev);
+ mutex_lock(&owner->rpm_lock);
+ if (data->domain) {
+ dev_dbg(data->sysmmu, "saving state\n");
+ __sysmmu_disable(data);
+ }
+ mutex_unlock(&owner->rpm_lock);
}
return 0;
}
-static int exynos_sysmmu_resume(struct device *dev)
+static int __maybe_unused exynos_sysmmu_resume(struct device *dev)
{
struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+ struct device *master = data->master;
+
+ if (master) {
+ struct exynos_iommu_owner *owner = master->archdata.iommu;
- dev_dbg(dev, "resume\n");
- if (is_sysmmu_active(data)) {
- pm_runtime_get_sync(dev);
- __sysmmu_enable_nocount(data);
+ mutex_lock(&owner->rpm_lock);
+ if (data->domain) {
+ dev_dbg(data->sysmmu, "restoring state\n");
+ __sysmmu_enable(data);
+ }
+ mutex_unlock(&owner->rpm_lock);
}
return 0;
}
-#endif
static const struct dev_pm_ops sysmmu_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(exynos_sysmmu_suspend, exynos_sysmmu_resume)
+ SET_RUNTIME_PM_OPS(exynos_sysmmu_suspend, exynos_sysmmu_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};
static const struct of_device_id sysmmu_of_match[] __initconst = {
@@ -796,9 +776,12 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
spin_lock_irqsave(&domain->lock, flags);
list_for_each_entry_safe(data, next, &domain->clients, domain_node) {
- if (__sysmmu_disable(data))
- data->master = NULL;
+ spin_lock(&data->lock);
+ __sysmmu_disable(data);
+ data->pgtable = 0;
+ data->domain = NULL;
list_del_init(&data->domain_node);
+ spin_unlock(&data->lock);
}
spin_unlock_irqrestore(&domain->lock, flags);
@@ -832,31 +815,34 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
phys_addr_t pagetable = virt_to_phys(domain->pgtable);
struct sysmmu_drvdata *data, *next;
unsigned long flags;
- bool found = false;
if (!has_sysmmu(dev) || owner->domain != iommu_domain)
return;
+ mutex_lock(&owner->rpm_lock);
+
+ list_for_each_entry(data, &owner->controllers, owner_node) {
+ pm_runtime_get_noresume(data->sysmmu);
+ if (pm_runtime_active(data->sysmmu))
+ __sysmmu_disable(data);
+ pm_runtime_put(data->sysmmu);
+ }
+
spin_lock_irqsave(&domain->lock, flags);
list_for_each_entry_safe(data, next, &domain->clients, domain_node) {
- if (data->master == dev) {
- if (__sysmmu_disable(data)) {
- data->master = NULL;
- list_del_init(&data->domain_node);
- }
- pm_runtime_put(data->sysmmu);
- found = true;
- }
+ spin_lock(&data->lock);
+ data->pgtable = 0;
+ data->domain = NULL;
+ list_del_init(&data->domain_node);
+ spin_unlock(&data->lock);
}
+ owner->domain = NULL;
spin_unlock_irqrestore(&domain->lock, flags);
- owner->domain = NULL;
+ mutex_unlock(&owner->rpm_lock);
- if (found)
- dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n",
- __func__, &pagetable);
- else
- dev_err(dev, "%s: No IOMMU is attached\n", __func__);
+ dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n", __func__,
+ &pagetable);
}
static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
@@ -867,7 +853,6 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
struct sysmmu_drvdata *data;
phys_addr_t pagetable = virt_to_phys(domain->pgtable);
unsigned long flags;
- int ret = -ENODEV;
if (!has_sysmmu(dev))
return -ENODEV;
@@ -875,29 +860,32 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
if (owner->domain)
exynos_iommu_detach_device(owner->domain, dev);
+ mutex_lock(&owner->rpm_lock);
+
+ spin_lock_irqsave(&domain->lock, flags);
list_for_each_entry(data, &owner->controllers, owner_node) {
- pm_runtime_get_sync(data->sysmmu);
- ret = __sysmmu_enable(data, pagetable, domain);
- if (ret >= 0) {
- data->master = dev;
-
- spin_lock_irqsave(&domain->lock, flags);
- list_add_tail(&data->domain_node, &domain->clients);
- spin_unlock_irqrestore(&domain->lock, flags);
- }
+ spin_lock(&data->lock);
+ data->pgtable = pagetable;
+ data->domain = domain;
+ list_add_tail(&data->domain_node, &domain->clients);
+ spin_unlock(&data->lock);
}
+ owner->domain = iommu_domain;
+ spin_unlock_irqrestore(&domain->lock, flags);
- if (ret < 0) {
- dev_err(dev, "%s: Failed to attach IOMMU with pgtable %pa\n",
- __func__, &pagetable);
- return ret;
+ list_for_each_entry(data, &owner->controllers, owner_node) {
+ pm_runtime_get_noresume(data->sysmmu);
+ if (pm_runtime_active(data->sysmmu))
+ __sysmmu_enable(data);
+ pm_runtime_put(data->sysmmu);
}
- owner->domain = iommu_domain;
- dev_dbg(dev, "%s: Attached IOMMU with pgtable %pa %s\n",
- __func__, &pagetable, (ret == 0) ? "" : ", again");
+ mutex_unlock(&owner->rpm_lock);
- return ret;
+ dev_dbg(dev, "%s: Attached IOMMU with pgtable %pa\n", __func__,
+ &pagetable);
+
+ return 0;
}
static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *domain,
@@ -954,7 +942,7 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *domain,
static int lv1set_section(struct exynos_iommu_domain *domain,
sysmmu_pte_t *sent, sysmmu_iova_t iova,
- phys_addr_t paddr, short *pgcnt)
+ phys_addr_t paddr, int prot, short *pgcnt)
{
if (lv1ent_section(sent)) {
WARN(1, "Trying mapping on 1MiB@%#08x that is mapped",
@@ -973,7 +961,7 @@ static int lv1set_section(struct exynos_iommu_domain *domain,
*pgcnt = 0;
}
- update_pte(sent, mk_lv1ent_sect(paddr));
+ update_pte(sent, mk_lv1ent_sect(paddr, prot));
spin_lock(&domain->lock);
if (lv1ent_page_zero(sent)) {
@@ -991,13 +979,13 @@ static int lv1set_section(struct exynos_iommu_domain *domain,
}
static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size,
- short *pgcnt)
+ int prot, short *pgcnt)
{
if (size == SPAGE_SIZE) {
if (WARN_ON(!lv2ent_fault(pent)))
return -EADDRINUSE;
- update_pte(pent, mk_lv2ent_spage(paddr));
+ update_pte(pent, mk_lv2ent_spage(paddr, prot));
*pgcnt -= 1;
} else { /* size == LPAGE_SIZE */
int i;
@@ -1013,7 +1001,7 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size,
return -EADDRINUSE;
}
- *pent = mk_lv2ent_lpage(paddr);
+ *pent = mk_lv2ent_lpage(paddr, prot);
}
dma_sync_single_for_device(dma_dev, pent_base,
sizeof(*pent) * SPAGES_PER_LPAGE,
@@ -1061,13 +1049,14 @@ static int exynos_iommu_map(struct iommu_domain *iommu_domain,
int ret = -ENOMEM;
BUG_ON(domain->pgtable == NULL);
+ prot &= SYSMMU_SUPPORTED_PROT_BITS;
spin_lock_irqsave(&domain->pgtablelock, flags);
entry = section_entry(domain->pgtable, iova);
if (size == SECT_SIZE) {
- ret = lv1set_section(domain, entry, iova, paddr,
+ ret = lv1set_section(domain, entry, iova, paddr, prot,
&domain->lv2entcnt[lv1ent_offset(iova)]);
} else {
sysmmu_pte_t *pent;
@@ -1078,7 +1067,7 @@ static int exynos_iommu_map(struct iommu_domain *iommu_domain,
if (IS_ERR(pent))
ret = PTR_ERR(pent);
else
- ret = lv2set_page(pent, paddr, size,
+ ret = lv2set_page(pent, paddr, size, prot,
&domain->lv2entcnt[lv1ent_offset(iova)]);
}
@@ -1268,10 +1257,20 @@ static int exynos_iommu_of_xlate(struct device *dev,
return -ENOMEM;
INIT_LIST_HEAD(&owner->controllers);
+ mutex_init(&owner->rpm_lock);
dev->archdata.iommu = owner;
}
list_add_tail(&data->owner_node, &owner->controllers);
+ data->master = dev;
+
+ /*
+ * SYSMMU will be runtime activated via device link (dependency) to its
+ * master device, so there are no direct calls to pm_runtime_get/put
+ * in this driver.
+ */
+ device_link_add(dev, data->sysmmu, DL_FLAG_PM_RUNTIME);
+
return 0;
}
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index f50e51c1a9c8..0769276c0537 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -793,8 +793,7 @@ static int __init arm_v7s_do_selftests(void)
* Distinct mappings of different granule sizes.
*/
iova = 0;
- i = find_first_bit(&cfg.pgsize_bitmap, BITS_PER_LONG);
- while (i != BITS_PER_LONG) {
+ for_each_set_bit(i, &cfg.pgsize_bitmap, BITS_PER_LONG) {
size = 1UL << i;
if (ops->map(ops, iova, iova, size, IOMMU_READ |
IOMMU_WRITE |
@@ -811,8 +810,6 @@ static int __init arm_v7s_do_selftests(void)
return __FAIL(ops);
iova += SZ_16M;
- i++;
- i = find_next_bit(&cfg.pgsize_bitmap, BITS_PER_LONG, i);
loopnr++;
}
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index f5c90e1366ce..a40ce3406fef 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -916,7 +916,7 @@ static void dummy_tlb_sync(void *cookie)
WARN_ON(cookie != cfg_cookie);
}
-static struct iommu_gather_ops dummy_tlb_ops __initdata = {
+static const struct iommu_gather_ops dummy_tlb_ops __initconst = {
.tlb_flush_all = dummy_tlb_flush_all,
.tlb_add_flush = dummy_tlb_add_flush,
.tlb_sync = dummy_tlb_sync,
@@ -980,8 +980,7 @@ static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg)
* Distinct mappings of different granule sizes.
*/
iova = 0;
- j = find_first_bit(&cfg->pgsize_bitmap, BITS_PER_LONG);
- while (j != BITS_PER_LONG) {
+ for_each_set_bit(j, &cfg->pgsize_bitmap, BITS_PER_LONG) {
size = 1UL << j;
if (ops->map(ops, iova, iova, size, IOMMU_READ |
@@ -999,8 +998,6 @@ static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg)
return __FAIL(ops, i);
iova += SZ_1G;
- j++;
- j = find_next_bit(&cfg->pgsize_bitmap, BITS_PER_LONG, j);
}
/* Partial unmap */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9a2f1960873b..dbe7f653bb7c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -552,6 +552,19 @@ struct iommu_group *iommu_group_get(struct device *dev)
EXPORT_SYMBOL_GPL(iommu_group_get);
/**
+ * iommu_group_ref_get - Increment reference on a group
+ * @group: the group to use, must not be NULL
+ *
+ * This function is called by iommu drivers to take additional references on an
+ * existing group. Returns the given group for convenience.
+ */
+struct iommu_group *iommu_group_ref_get(struct iommu_group *group)
+{
+ kobject_get(group->devices_kobj);
+ return group;
+}
+
+/**
* iommu_group_put - Decrement group reference
* @group: the group to use
*
@@ -1615,6 +1628,46 @@ out:
return ret;
}
+struct iommu_instance {
+ struct list_head list;
+ struct fwnode_handle *fwnode;
+ const struct iommu_ops *ops;
+};
+static LIST_HEAD(iommu_instance_list);
+static DEFINE_SPINLOCK(iommu_instance_lock);
+
+void iommu_register_instance(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops)
+{
+ struct iommu_instance *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+
+ if (WARN_ON(!iommu))
+ return;
+
+ of_node_get(to_of_node(fwnode));
+ INIT_LIST_HEAD(&iommu->list);
+ iommu->fwnode = fwnode;
+ iommu->ops = ops;
+ spin_lock(&iommu_instance_lock);
+ list_add_tail(&iommu->list, &iommu_instance_list);
+ spin_unlock(&iommu_instance_lock);
+}
+
+const struct iommu_ops *iommu_get_instance(struct fwnode_handle *fwnode)
+{
+ struct iommu_instance *instance;
+ const struct iommu_ops *ops = NULL;
+
+ spin_lock(&iommu_instance_lock);
+ list_for_each_entry(instance, &iommu_instance_list, list)
+ if (instance->fwnode == fwnode) {
+ ops = instance->ops;
+ break;
+ }
+ spin_unlock(&iommu_instance_lock);
+ return ops;
+}
+
int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
const struct iommu_ops *ops)
{
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index e23001bfcfee..080beca0197d 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -56,7 +56,7 @@ EXPORT_SYMBOL_GPL(init_iova_domain);
static struct rb_node *
__get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
{
- if ((*limit_pfn != iovad->dma_32bit_pfn) ||
+ if ((*limit_pfn > iovad->dma_32bit_pfn) ||
(iovad->cached32_node == NULL))
return rb_last(&iovad->rbroot);
else {
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b12c12d74c33..1479c76ece9e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -195,14 +195,14 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
static void mtk_iommu_config(struct mtk_iommu_data *data,
struct device *dev, bool enable)
{
- struct mtk_iommu_client_priv *head, *cur, *next;
struct mtk_smi_larb_iommu *larb_mmu;
unsigned int larbid, portid;
+ struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+ int i;
- head = dev->archdata.iommu;
- list_for_each_entry_safe(cur, next, &head->client, client) {
- larbid = MTK_M4U_TO_LARB(cur->mtk_m4u_id);
- portid = MTK_M4U_TO_PORT(cur->mtk_m4u_id);
+ for (i = 0; i < fwspec->num_ids; ++i) {
+ larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
+ portid = MTK_M4U_TO_PORT(fwspec->ids[i]);
larb_mmu = &data->smi_imu.larb_imu[larbid];
dev_dbg(dev, "%s iommu port: %d\n",
@@ -282,14 +282,12 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
- struct mtk_iommu_client_priv *priv = dev->archdata.iommu;
- struct mtk_iommu_data *data;
+ struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
int ret;
- if (!priv)
+ if (!data)
return -ENODEV;
- data = dev_get_drvdata(priv->m4udev);
if (!data->m4u_dom) {
data->m4u_dom = dom;
ret = mtk_iommu_domain_finalise(data);
@@ -310,13 +308,11 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
static void mtk_iommu_detach_device(struct iommu_domain *domain,
struct device *dev)
{
- struct mtk_iommu_client_priv *priv = dev->archdata.iommu;
- struct mtk_iommu_data *data;
+ struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
- if (!priv)
+ if (!data)
return;
- data = dev_get_drvdata(priv->m4udev);
mtk_iommu_config(data, dev, false);
}
@@ -366,8 +362,8 @@ static int mtk_iommu_add_device(struct device *dev)
{
struct iommu_group *group;
- if (!dev->archdata.iommu) /* Not a iommu client device */
- return -ENODEV;
+ if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
+ return -ENODEV; /* Not a iommu client device */
group = iommu_group_get_for_dev(dev);
if (IS_ERR(group))
@@ -379,44 +375,33 @@ static int mtk_iommu_add_device(struct device *dev)
static void mtk_iommu_remove_device(struct device *dev)
{
- struct mtk_iommu_client_priv *head, *cur, *next;
-
- head = dev->archdata.iommu;
- if (!head)
+ if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
return;
- list_for_each_entry_safe(cur, next, &head->client, client) {
- list_del(&cur->client);
- kfree(cur);
- }
- kfree(head);
- dev->archdata.iommu = NULL;
-
iommu_group_remove_device(dev);
+ iommu_fwspec_free(dev);
}
static struct iommu_group *mtk_iommu_device_group(struct device *dev)
{
- struct mtk_iommu_data *data;
- struct mtk_iommu_client_priv *priv;
+ struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
- priv = dev->archdata.iommu;
- if (!priv)
+ if (!data)
return ERR_PTR(-ENODEV);
/* All the client devices are in the same m4u iommu-group */
- data = dev_get_drvdata(priv->m4udev);
if (!data->m4u_group) {
data->m4u_group = iommu_group_alloc();
if (IS_ERR(data->m4u_group))
dev_err(dev, "Failed to allocate M4U IOMMU group\n");
+ } else {
+ iommu_group_ref_get(data->m4u_group);
}
return data->m4u_group;
}
static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
{
- struct mtk_iommu_client_priv *head, *priv, *next;
struct platform_device *m4updev;
if (args->args_count != 1) {
@@ -425,38 +410,16 @@ static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
return -EINVAL;
}
- if (!dev->archdata.iommu) {
+ if (!dev->iommu_fwspec->iommu_priv) {
/* Get the m4u device */
m4updev = of_find_device_by_node(args->np);
if (WARN_ON(!m4updev))
return -EINVAL;
- head = kzalloc(sizeof(*head), GFP_KERNEL);
- if (!head)
- return -ENOMEM;
-
- dev->archdata.iommu = head;
- INIT_LIST_HEAD(&head->client);
- head->m4udev = &m4updev->dev;
- } else {
- head = dev->archdata.iommu;
+ dev->iommu_fwspec->iommu_priv = platform_get_drvdata(m4updev);
}
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- goto err_free_mem;
-
- priv->mtk_m4u_id = args->args[0];
- list_add_tail(&priv->client, &head->client);
-
- return 0;
-
-err_free_mem:
- list_for_each_entry_safe(priv, next, &head->client, client)
- kfree(priv);
- kfree(head);
- dev->archdata.iommu = NULL;
- return -ENOMEM;
+ return iommu_fwspec_add_ids(dev, args->args, 1);
}
static struct iommu_ops mtk_iommu_ops = {
@@ -583,17 +546,19 @@ static int mtk_iommu_probe(struct platform_device *pdev)
continue;
plarbdev = of_find_device_by_node(larbnode);
- of_node_put(larbnode);
if (!plarbdev) {
plarbdev = of_platform_device_create(
larbnode, NULL,
platform_bus_type.dev_root);
- if (!plarbdev)
+ if (!plarbdev) {
+ of_node_put(larbnode);
return -EPROBE_DEFER;
+ }
}
data->smi_imu.larb_imu[i].dev = &plarbdev->dev;
- component_match_add(dev, &match, compare_of, larbnode);
+ component_match_add_release(dev, &match, release_of,
+ compare_of, larbnode);
}
platform_set_drvdata(pdev, data);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 3dab13b4a211..50177f738e4e 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -34,12 +34,6 @@ struct mtk_iommu_suspend_reg {
u32 int_main_control;
};
-struct mtk_iommu_client_priv {
- struct list_head client;
- unsigned int mtk_m4u_id;
- struct device *m4udev;
-};
-
struct mtk_iommu_domain;
struct mtk_iommu_data {
@@ -60,6 +54,11 @@ static inline int compare_of(struct device *dev, void *data)
return dev->of_node == data;
}
+static inline void release_of(struct device *dev, void *data)
+{
+ of_node_put(data);
+}
+
static inline int mtk_iommu_bind(struct device *dev)
{
struct mtk_iommu_data *data = dev_get_drvdata(dev);
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index b8aeb0768483..19e010083408 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -204,14 +204,14 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
static void mtk_iommu_config(struct mtk_iommu_data *data,
struct device *dev, bool enable)
{
- struct mtk_iommu_client_priv *head, *cur, *next;
struct mtk_smi_larb_iommu *larb_mmu;
unsigned int larbid, portid;
+ struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+ int i;
- head = dev->archdata.iommu;
- list_for_each_entry_safe(cur, next, &head->client, client) {
- larbid = mt2701_m4u_to_larb(cur->mtk_m4u_id);
- portid = mt2701_m4u_to_port(cur->mtk_m4u_id);
+ for (i = 0; i < fwspec->num_ids; ++i) {
+ larbid = mt2701_m4u_to_larb(fwspec->ids[i]);
+ portid = mt2701_m4u_to_port(fwspec->ids[i]);
larb_mmu = &data->smi_imu.larb_imu[larbid];
dev_dbg(dev, "%s iommu port: %d\n",
@@ -271,14 +271,12 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
- struct mtk_iommu_client_priv *priv = dev->archdata.iommu;
- struct mtk_iommu_data *data;
+ struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
int ret;
- if (!priv)
+ if (!data)
return -ENODEV;
- data = dev_get_drvdata(priv->m4udev);
if (!data->m4u_dom) {
data->m4u_dom = dom;
ret = mtk_iommu_domain_finalise(data);
@@ -295,13 +293,11 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
static void mtk_iommu_detach_device(struct iommu_domain *domain,
struct device *dev)
{
- struct mtk_iommu_client_priv *priv = dev->archdata.iommu;
- struct mtk_iommu_data *data;
+ struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
- if (!priv)
+ if (!data)
return;
- data = dev_get_drvdata(priv->m4udev);
mtk_iommu_config(data, dev, false);
}
@@ -366,6 +362,8 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
return pa;
}
+static struct iommu_ops mtk_iommu_ops;
+
/*
* MTK generation one iommu HW only support one iommu domain, and all the client
* sharing the same iova address space.
@@ -373,7 +371,7 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
static int mtk_iommu_create_mapping(struct device *dev,
struct of_phandle_args *args)
{
- struct mtk_iommu_client_priv *head, *priv, *next;
+ struct mtk_iommu_data *data;
struct platform_device *m4updev;
struct dma_iommu_mapping *mtk_mapping;
struct device *m4udev;
@@ -385,41 +383,37 @@ static int mtk_iommu_create_mapping(struct device *dev,
return -EINVAL;
}
- if (!dev->archdata.iommu) {
+ if (!dev->iommu_fwspec) {
+ ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_ops);
+ if (ret)
+ return ret;
+ } else if (dev->iommu_fwspec->ops != &mtk_iommu_ops) {
+ return -EINVAL;
+ }
+
+ if (!dev->iommu_fwspec->iommu_priv) {
/* Get the m4u device */
m4updev = of_find_device_by_node(args->np);
if (WARN_ON(!m4updev))
return -EINVAL;
- head = kzalloc(sizeof(*head), GFP_KERNEL);
- if (!head)
- return -ENOMEM;
-
- dev->archdata.iommu = head;
- INIT_LIST_HEAD(&head->client);
- head->m4udev = &m4updev->dev;
- } else {
- head = dev->archdata.iommu;
+ dev->iommu_fwspec->iommu_priv = platform_get_drvdata(m4updev);
}
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- goto err_free_mem;
- }
- priv->mtk_m4u_id = args->args[0];
- list_add_tail(&priv->client, &head->client);
+ ret = iommu_fwspec_add_ids(dev, args->args, 1);
+ if (ret)
+ return ret;
- m4udev = head->m4udev;
+ data = dev->iommu_fwspec->iommu_priv;
+ m4udev = data->dev;
mtk_mapping = m4udev->archdata.iommu;
if (!mtk_mapping) {
/* MTK iommu support 4GB iova address space. */
mtk_mapping = arm_iommu_create_mapping(&platform_bus_type,
0, 1ULL << 32);
- if (IS_ERR(mtk_mapping)) {
- ret = PTR_ERR(mtk_mapping);
- goto err_free_mem;
- }
+ if (IS_ERR(mtk_mapping))
+ return PTR_ERR(mtk_mapping);
+
m4udev->archdata.iommu = mtk_mapping;
}
@@ -432,11 +426,6 @@ static int mtk_iommu_create_mapping(struct device *dev,
err_release_mapping:
arm_iommu_release_mapping(mtk_mapping);
m4udev->archdata.iommu = NULL;
-err_free_mem:
- list_for_each_entry_safe(priv, next, &head->client, client)
- kfree(priv);
- kfree(head);
- dev->archdata.iommu = NULL;
return ret;
}
@@ -458,8 +447,8 @@ static int mtk_iommu_add_device(struct device *dev)
of_node_put(iommu_spec.np);
}
- if (!dev->archdata.iommu) /* Not a iommu client device */
- return -ENODEV;
+ if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
+ return -ENODEV; /* Not a iommu client device */
group = iommu_group_get_for_dev(dev);
if (IS_ERR(group))
@@ -471,37 +460,27 @@ static int mtk_iommu_add_device(struct device *dev)
static void mtk_iommu_remove_device(struct device *dev)
{
- struct mtk_iommu_client_priv *head, *cur, *next;
-
- head = dev->archdata.iommu;
- if (!head)
+ if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
return;
- list_for_each_entry_safe(cur, next, &head->client, client) {
- list_del(&cur->client);
- kfree(cur);
- }
- kfree(head);
- dev->archdata.iommu = NULL;
-
iommu_group_remove_device(dev);
+ iommu_fwspec_free(dev);
}
static struct iommu_group *mtk_iommu_device_group(struct device *dev)
{
- struct mtk_iommu_data *data;
- struct mtk_iommu_client_priv *priv;
+ struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
- priv = dev->archdata.iommu;
- if (!priv)
+ if (!data)
return ERR_PTR(-ENODEV);
/* All the client devices are in the same m4u iommu-group */
- data = dev_get_drvdata(priv->m4udev);
if (!data->m4u_group) {
data->m4u_group = iommu_group_alloc();
if (IS_ERR(data->m4u_group))
dev_err(dev, "Failed to allocate M4U IOMMU group\n");
+ } else {
+ iommu_group_ref_get(data->m4u_group);
}
return data->m4u_group;
}
@@ -624,17 +603,19 @@ static int mtk_iommu_probe(struct platform_device *pdev)
continue;
plarbdev = of_find_device_by_node(larb_spec.np);
- of_node_put(larb_spec.np);
if (!plarbdev) {
plarbdev = of_platform_device_create(
larb_spec.np, NULL,
platform_bus_type.dev_root);
- if (!plarbdev)
+ if (!plarbdev) {
+ of_node_put(larb_spec.np);
return -EPROBE_DEFER;
+ }
}
data->smi_imu.larb_imu[larb_nr].dev = &plarbdev->dev;
- component_match_add(dev, &match, compare_of, larb_spec.np);
+ component_match_add_release(dev, &match, release_of,
+ compare_of, larb_spec.np);
larb_nr++;
}
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 5b82862f571f..0f57ddc4ecc2 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,45 +96,6 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
}
EXPORT_SYMBOL_GPL(of_get_dma_window);
-struct of_iommu_node {
- struct list_head list;
- struct device_node *np;
- const struct iommu_ops *ops;
-};
-static LIST_HEAD(of_iommu_list);
-static DEFINE_SPINLOCK(of_iommu_lock);
-
-void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops)
-{
- struct of_iommu_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
-
- if (WARN_ON(!iommu))
- return;
-
- of_node_get(np);
- INIT_LIST_HEAD(&iommu->list);
- iommu->np = np;
- iommu->ops = ops;
- spin_lock(&of_iommu_lock);
- list_add_tail(&iommu->list, &of_iommu_list);
- spin_unlock(&of_iommu_lock);
-}
-
-const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
-{
- struct of_iommu_node *node;
- const struct iommu_ops *ops = NULL;
-
- spin_lock(&of_iommu_lock);
- list_for_each_entry(node, &of_iommu_list, list)
- if (node->np == np) {
- ops = node->ops;
- break;
- }
- spin_unlock(&of_iommu_lock);
- return ops;
-}
-
static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
{
struct of_phandle_args *iommu_spec = data;
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index 3b44b1d82f3b..179e636a4d91 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -8,7 +8,6 @@
#include <linux/pci.h>
#include <linux/iommu.h>
#include <linux/iommu-helper.h>
-#include <linux/pci.h>
#include <linux/sizes.h>
#include <asm/pci_dma.h>
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 11eebfe8a4cb..ceff415f201c 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -124,6 +124,15 @@ config MAILBOX_TEST
Test client to help with testing new Controller driver
implementations.
+config TEGRA_HSP_MBOX
+ bool "Tegra HSP (Hardware Synchronization Primitives) Driver"
+ depends on ARCH_TEGRA_186_SOC
+ help
+ The Tegra HSP driver is used for the interprocessor communication
+ between different remote processors and host processors on Tegra186
+ and later SoCs. Say Y here if you want to have this support.
+ If unsure say N.
+
config XGENE_SLIMPRO_MBOX
tristate "APM SoC X-Gene SLIMpro Mailbox Controller"
depends on ARCH_XGENE
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index ace6fed8fea9..7dde4f609ae8 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -29,3 +29,5 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
obj-$(CONFIG_HI6220_MBOX) += hi6220-mailbox.o
obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
+
+obj-$(CONFIG_TEGRA_HSP_MBOX) += tegra-hsp.o
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
new file mode 100644
index 000000000000..0cde356c11ab
--- /dev/null
+++ b/drivers/mailbox/tegra-hsp.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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/interrupt.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/mailbox/tegra186-hsp.h>
+
+#define HSP_INT_DIMENSIONING 0x380
+#define HSP_nSM_SHIFT 0
+#define HSP_nSS_SHIFT 4
+#define HSP_nAS_SHIFT 8
+#define HSP_nDB_SHIFT 12
+#define HSP_nSI_SHIFT 16
+#define HSP_nINT_MASK 0xf
+
+#define HSP_DB_TRIGGER 0x0
+#define HSP_DB_ENABLE 0x4
+#define HSP_DB_RAW 0x8
+#define HSP_DB_PENDING 0xc
+
+#define HSP_DB_CCPLEX 1
+#define HSP_DB_BPMP 3
+#define HSP_DB_MAX 7
+
+struct tegra_hsp_channel;
+struct tegra_hsp;
+
+struct tegra_hsp_channel {
+ struct tegra_hsp *hsp;
+ struct mbox_chan *chan;
+ void __iomem *regs;
+};
+
+struct tegra_hsp_doorbell {
+ struct tegra_hsp_channel channel;
+ struct list_head list;
+ const char *name;
+ unsigned int master;
+ unsigned int index;
+};
+
+struct tegra_hsp_db_map {
+ const char *name;
+ unsigned int master;
+ unsigned int index;
+};
+
+struct tegra_hsp_soc {
+ const struct tegra_hsp_db_map *map;
+};
+
+struct tegra_hsp {
+ const struct tegra_hsp_soc *soc;
+ struct mbox_controller mbox;
+ void __iomem *regs;
+ unsigned int irq;
+ unsigned int num_sm;
+ unsigned int num_as;
+ unsigned int num_ss;
+ unsigned int num_db;
+ unsigned int num_si;
+ spinlock_t lock;
+
+ struct list_head doorbells;
+};
+
+static inline struct tegra_hsp *
+to_tegra_hsp(struct mbox_controller *mbox)
+{
+ return container_of(mbox, struct tegra_hsp, mbox);
+}
+
+static inline u32 tegra_hsp_readl(struct tegra_hsp *hsp, unsigned int offset)
+{
+ return readl(hsp->regs + offset);
+}
+
+static inline void tegra_hsp_writel(struct tegra_hsp *hsp, u32 value,
+ unsigned int offset)
+{
+ writel(value, hsp->regs + offset);
+}
+
+static inline u32 tegra_hsp_channel_readl(struct tegra_hsp_channel *channel,
+ unsigned int offset)
+{
+ return readl(channel->regs + offset);
+}
+
+static inline void tegra_hsp_channel_writel(struct tegra_hsp_channel *channel,
+ u32 value, unsigned int offset)
+{
+ writel(value, channel->regs + offset);
+}
+
+static bool tegra_hsp_doorbell_can_ring(struct tegra_hsp_doorbell *db)
+{
+ u32 value;
+
+ value = tegra_hsp_channel_readl(&db->channel, HSP_DB_ENABLE);
+
+ return (value & BIT(TEGRA_HSP_DB_MASTER_CCPLEX)) != 0;
+}
+
+static struct tegra_hsp_doorbell *
+__tegra_hsp_doorbell_get(struct tegra_hsp *hsp, unsigned int master)
+{
+ struct tegra_hsp_doorbell *entry;
+
+ list_for_each_entry(entry, &hsp->doorbells, list)
+ if (entry->master == master)
+ return entry;
+
+ return NULL;
+}
+
+static struct tegra_hsp_doorbell *
+tegra_hsp_doorbell_get(struct tegra_hsp *hsp, unsigned int master)
+{
+ struct tegra_hsp_doorbell *db;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hsp->lock, flags);
+ db = __tegra_hsp_doorbell_get(hsp, master);
+ spin_unlock_irqrestore(&hsp->lock, flags);
+
+ return db;
+}
+
+static irqreturn_t tegra_hsp_doorbell_irq(int irq, void *data)
+{
+ struct tegra_hsp *hsp = data;
+ struct tegra_hsp_doorbell *db;
+ unsigned long master, value;
+
+ db = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
+ if (!db)
+ return IRQ_NONE;
+
+ value = tegra_hsp_channel_readl(&db->channel, HSP_DB_PENDING);
+ tegra_hsp_channel_writel(&db->channel, value, HSP_DB_PENDING);
+
+ spin_lock(&hsp->lock);
+
+ for_each_set_bit(master, &value, hsp->mbox.num_chans) {
+ struct tegra_hsp_doorbell *db;
+
+ db = __tegra_hsp_doorbell_get(hsp, master);
+ /*
+ * Depending on the bootloader chain, the CCPLEX doorbell will
+ * have some doorbells enabled, which means that requesting an
+ * interrupt will immediately fire.
+ *
+ * In that case, db->channel.chan will still be NULL here and
+ * cause a crash if not properly guarded.
+ *
+ * It remains to be seen if ignoring the doorbell in that case
+ * is the correct solution.
+ */
+ if (db && db->channel.chan)
+ mbox_chan_received_data(db->channel.chan, NULL);
+ }
+
+ spin_unlock(&hsp->lock);
+
+ return IRQ_HANDLED;
+}
+
+static struct tegra_hsp_channel *
+tegra_hsp_doorbell_create(struct tegra_hsp *hsp, const char *name,
+ unsigned int master, unsigned int index)
+{
+ struct tegra_hsp_doorbell *db;
+ unsigned int offset;
+ unsigned long flags;
+
+ db = kzalloc(sizeof(*db), GFP_KERNEL);
+ if (!db)
+ return ERR_PTR(-ENOMEM);
+
+ offset = (1 + (hsp->num_sm / 2) + hsp->num_ss + hsp->num_as) << 16;
+ offset += index * 0x100;
+
+ db->channel.regs = hsp->regs + offset;
+ db->channel.hsp = hsp;
+
+ db->name = kstrdup_const(name, GFP_KERNEL);
+ db->master = master;
+ db->index = index;
+
+ spin_lock_irqsave(&hsp->lock, flags);
+ list_add_tail(&db->list, &hsp->doorbells);
+ spin_unlock_irqrestore(&hsp->lock, flags);
+
+ return &db->channel;
+}
+
+static void __tegra_hsp_doorbell_destroy(struct tegra_hsp_doorbell *db)
+{
+ list_del(&db->list);
+ kfree_const(db->name);
+ kfree(db);
+}
+
+static int tegra_hsp_doorbell_send_data(struct mbox_chan *chan, void *data)
+{
+ struct tegra_hsp_doorbell *db = chan->con_priv;
+
+ tegra_hsp_channel_writel(&db->channel, 1, HSP_DB_TRIGGER);
+
+ return 0;
+}
+
+static int tegra_hsp_doorbell_startup(struct mbox_chan *chan)
+{
+ struct tegra_hsp_doorbell *db = chan->con_priv;
+ struct tegra_hsp *hsp = db->channel.hsp;
+ struct tegra_hsp_doorbell *ccplex;
+ unsigned long flags;
+ u32 value;
+
+ if (db->master >= hsp->mbox.num_chans) {
+ dev_err(hsp->mbox.dev,
+ "invalid master ID %u for HSP channel\n",
+ db->master);
+ return -EINVAL;
+ }
+
+ ccplex = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
+ if (!ccplex)
+ return -ENODEV;
+
+ if (!tegra_hsp_doorbell_can_ring(db))
+ return -ENODEV;
+
+ spin_lock_irqsave(&hsp->lock, flags);
+
+ value = tegra_hsp_channel_readl(&ccplex->channel, HSP_DB_ENABLE);
+ value |= BIT(db->master);
+ tegra_hsp_channel_writel(&ccplex->channel, value, HSP_DB_ENABLE);
+
+ spin_unlock_irqrestore(&hsp->lock, flags);
+
+ return 0;
+}
+
+static void tegra_hsp_doorbell_shutdown(struct mbox_chan *chan)
+{
+ struct tegra_hsp_doorbell *db = chan->con_priv;
+ struct tegra_hsp *hsp = db->channel.hsp;
+ struct tegra_hsp_doorbell *ccplex;
+ unsigned long flags;
+ u32 value;
+
+ ccplex = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
+ if (!ccplex)
+ return;
+
+ spin_lock_irqsave(&hsp->lock, flags);
+
+ value = tegra_hsp_channel_readl(&ccplex->channel, HSP_DB_ENABLE);
+ value &= ~BIT(db->master);
+ tegra_hsp_channel_writel(&ccplex->channel, value, HSP_DB_ENABLE);
+
+ spin_unlock_irqrestore(&hsp->lock, flags);
+}
+
+static const struct mbox_chan_ops tegra_hsp_doorbell_ops = {
+ .send_data = tegra_hsp_doorbell_send_data,
+ .startup = tegra_hsp_doorbell_startup,
+ .shutdown = tegra_hsp_doorbell_shutdown,
+};
+
+static struct mbox_chan *of_tegra_hsp_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *args)
+{
+ struct tegra_hsp_channel *channel = ERR_PTR(-ENODEV);
+ struct tegra_hsp *hsp = to_tegra_hsp(mbox);
+ unsigned int type = args->args[0];
+ unsigned int master = args->args[1];
+ struct tegra_hsp_doorbell *db;
+ struct mbox_chan *chan;
+ unsigned long flags;
+ unsigned int i;
+
+ switch (type) {
+ case TEGRA_HSP_MBOX_TYPE_DB:
+ db = tegra_hsp_doorbell_get(hsp, master);
+ if (db)
+ channel = &db->channel;
+
+ break;
+
+ default:
+ break;
+ }
+
+ if (IS_ERR(channel))
+ return ERR_CAST(channel);
+
+ spin_lock_irqsave(&hsp->lock, flags);
+
+ for (i = 0; i < hsp->mbox.num_chans; i++) {
+ chan = &hsp->mbox.chans[i];
+ if (!chan->con_priv) {
+ chan->con_priv = channel;
+ channel->chan = chan;
+ break;
+ }
+
+ chan = NULL;
+ }
+
+ spin_unlock_irqrestore(&hsp->lock, flags);
+
+ return chan ?: ERR_PTR(-EBUSY);
+}
+
+static void tegra_hsp_remove_doorbells(struct tegra_hsp *hsp)
+{
+ struct tegra_hsp_doorbell *db, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hsp->lock, flags);
+
+ list_for_each_entry_safe(db, tmp, &hsp->doorbells, list)
+ __tegra_hsp_doorbell_destroy(db);
+
+ spin_unlock_irqrestore(&hsp->lock, flags);
+}
+
+static int tegra_hsp_add_doorbells(struct tegra_hsp *hsp)
+{
+ const struct tegra_hsp_db_map *map = hsp->soc->map;
+ struct tegra_hsp_channel *channel;
+
+ while (map->name) {
+ channel = tegra_hsp_doorbell_create(hsp, map->name,
+ map->master, map->index);
+ if (IS_ERR(channel)) {
+ tegra_hsp_remove_doorbells(hsp);
+ return PTR_ERR(channel);
+ }
+
+ map++;
+ }
+
+ return 0;
+}
+
+static int tegra_hsp_probe(struct platform_device *pdev)
+{
+ struct tegra_hsp *hsp;
+ struct resource *res;
+ u32 value;
+ int err;
+
+ hsp = devm_kzalloc(&pdev->dev, sizeof(*hsp), GFP_KERNEL);
+ if (!hsp)
+ return -ENOMEM;
+
+ hsp->soc = of_device_get_match_data(&pdev->dev);
+ INIT_LIST_HEAD(&hsp->doorbells);
+ spin_lock_init(&hsp->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hsp->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(hsp->regs))
+ return PTR_ERR(hsp->regs);
+
+ value = tegra_hsp_readl(hsp, HSP_INT_DIMENSIONING);
+ hsp->num_sm = (value >> HSP_nSM_SHIFT) & HSP_nINT_MASK;
+ hsp->num_ss = (value >> HSP_nSS_SHIFT) & HSP_nINT_MASK;
+ hsp->num_as = (value >> HSP_nAS_SHIFT) & HSP_nINT_MASK;
+ hsp->num_db = (value >> HSP_nDB_SHIFT) & HSP_nINT_MASK;
+ hsp->num_si = (value >> HSP_nSI_SHIFT) & HSP_nINT_MASK;
+
+ err = platform_get_irq_byname(pdev, "doorbell");
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to get doorbell IRQ: %d\n", err);
+ return err;
+ }
+
+ hsp->irq = err;
+
+ hsp->mbox.of_xlate = of_tegra_hsp_xlate;
+ hsp->mbox.num_chans = 32;
+ hsp->mbox.dev = &pdev->dev;
+ hsp->mbox.txdone_irq = false;
+ hsp->mbox.txdone_poll = false;
+ hsp->mbox.ops = &tegra_hsp_doorbell_ops;
+
+ hsp->mbox.chans = devm_kcalloc(&pdev->dev, hsp->mbox.num_chans,
+ sizeof(*hsp->mbox.chans),
+ GFP_KERNEL);
+ if (!hsp->mbox.chans)
+ return -ENOMEM;
+
+ err = tegra_hsp_add_doorbells(hsp);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to add doorbells: %d\n", err);
+ return err;
+ }
+
+ platform_set_drvdata(pdev, hsp);
+
+ err = mbox_controller_register(&hsp->mbox);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register mailbox: %d\n", err);
+ tegra_hsp_remove_doorbells(hsp);
+ return err;
+ }
+
+ err = devm_request_irq(&pdev->dev, hsp->irq, tegra_hsp_doorbell_irq,
+ IRQF_NO_SUSPEND, dev_name(&pdev->dev), hsp);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n",
+ hsp->irq, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int tegra_hsp_remove(struct platform_device *pdev)
+{
+ struct tegra_hsp *hsp = platform_get_drvdata(pdev);
+
+ mbox_controller_unregister(&hsp->mbox);
+ tegra_hsp_remove_doorbells(hsp);
+
+ return 0;
+}
+
+static const struct tegra_hsp_db_map tegra186_hsp_db_map[] = {
+ { "ccplex", TEGRA_HSP_DB_MASTER_CCPLEX, HSP_DB_CCPLEX, },
+ { "bpmp", TEGRA_HSP_DB_MASTER_BPMP, HSP_DB_BPMP, },
+ { /* sentinel */ }
+};
+
+static const struct tegra_hsp_soc tegra186_hsp_soc = {
+ .map = tegra186_hsp_db_map,
+};
+
+static const struct of_device_id tegra_hsp_match[] = {
+ { .compatible = "nvidia,tegra186-hsp", .data = &tegra186_hsp_soc },
+ { }
+};
+
+static struct platform_driver tegra_hsp_driver = {
+ .driver = {
+ .name = "tegra-hsp",
+ .of_match_table = tegra_hsp_match,
+ },
+ .probe = tegra_hsp_probe,
+ .remove = tegra_hsp_remove,
+};
+
+static int __init tegra_hsp_init(void)
+{
+ return platform_driver_register(&tegra_hsp_driver);
+}
+core_initcall(tegra_hsp_init);
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 4b4c0c3c3d2f..ec80e35c8dfe 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -134,6 +134,14 @@ config MTK_SMI
mainly help enable/disable iommu and control the power domain and
clocks for each local arbiter.
+config DA8XX_DDRCTL
+ bool "Texas Instruments da8xx DDR2/mDDR driver"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ This driver is for the DDR2/mDDR Memory Controller present on
+ Texas Instruments da8xx SoCs. It's used to tweak various memory
+ controller configuration options.
+
source "drivers/memory/samsung/Kconfig"
source "drivers/memory/tegra/Kconfig"
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index b20ae38b5bfb..e88097fbc085 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
obj-$(CONFIG_MTK_SMI) += mtk-smi.o
+obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
obj-$(CONFIG_SAMSUNG_MC) += samsung/
obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index b5ed3bd082b5..047d6fcdcec2 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -657,7 +657,7 @@ static int at91_ebi_dev_disable(struct at91_ebi *ebi, struct device_node *np)
return -ENOMEM;
newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
- if (!newprop->name)
+ if (!newprop->value)
return -ENOMEM;
newprop->length = sizeof("disabled");
diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c
index 12080b05e3e6..b418b39af180 100644
--- a/drivers/memory/atmel-sdramc.c
+++ b/drivers/memory/atmel-sdramc.c
@@ -85,8 +85,4 @@ static struct platform_driver atmel_ramc_driver = {
},
};
-static int __init atmel_ramc_init(void)
-{
- return platform_driver_register(&atmel_ramc_driver);
-}
-device_initcall(atmel_ramc_init);
+builtin_platform_driver(atmel_ramc_driver);
diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
new file mode 100644
index 000000000000..030afbe29d0c
--- /dev/null
+++ b/drivers/memory/da8xx-ddrctl.c
@@ -0,0 +1,173 @@
+/*
+ * TI da8xx DDR2/mDDR controller driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.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/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+struct da8xx_ddrctl_config_knob {
+ const char *name;
+ u32 reg;
+ u32 mask;
+ u32 shift;
+};
+
+static const struct da8xx_ddrctl_config_knob da8xx_ddrctl_knobs[] = {
+ {
+ .name = "da850-pbbpr",
+ .reg = 0x20,
+ .mask = 0xffffff00,
+ .shift = 0,
+ },
+};
+
+struct da8xx_ddrctl_setting {
+ const char *name;
+ u32 val;
+};
+
+struct da8xx_ddrctl_board_settings {
+ const char *board;
+ const struct da8xx_ddrctl_setting *settings;
+};
+
+static const struct da8xx_ddrctl_setting da850_lcdk_ddrctl_settings[] = {
+ {
+ .name = "da850-pbbpr",
+ .val = 0x20,
+ },
+ { }
+};
+
+static const struct da8xx_ddrctl_board_settings da8xx_ddrctl_board_confs[] = {
+ {
+ .board = "ti,da850-lcdk",
+ .settings = da850_lcdk_ddrctl_settings,
+ },
+};
+
+static const struct da8xx_ddrctl_config_knob *
+da8xx_ddrctl_match_knob(const struct da8xx_ddrctl_setting *setting)
+{
+ const struct da8xx_ddrctl_config_knob *knob;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_knobs); i++) {
+ knob = &da8xx_ddrctl_knobs[i];
+
+ if (strcmp(knob->name, setting->name) == 0)
+ return knob;
+ }
+
+ return NULL;
+}
+
+static const struct da8xx_ddrctl_setting *da8xx_ddrctl_get_board_settings(void)
+{
+ const struct da8xx_ddrctl_board_settings *board_settings;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_board_confs); i++) {
+ board_settings = &da8xx_ddrctl_board_confs[i];
+
+ if (of_machine_is_compatible(board_settings->board))
+ return board_settings->settings;
+ }
+
+ return NULL;
+}
+
+static int da8xx_ddrctl_probe(struct platform_device *pdev)
+{
+ const struct da8xx_ddrctl_config_knob *knob;
+ const struct da8xx_ddrctl_setting *setting;
+ struct device_node *node;
+ struct resource *res;
+ void __iomem *ddrctl;
+ struct device *dev;
+ u32 reg;
+
+ dev = &pdev->dev;
+ node = dev->of_node;
+
+ setting = da8xx_ddrctl_get_board_settings();
+ if (!setting) {
+ dev_err(dev, "no settings defined for this board\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ddrctl = devm_ioremap_resource(dev, res);
+ if (IS_ERR(ddrctl)) {
+ dev_err(dev, "unable to map memory controller registers\n");
+ return PTR_ERR(ddrctl);
+ }
+
+ for (; setting->name; setting++) {
+ knob = da8xx_ddrctl_match_knob(setting);
+ if (!knob) {
+ dev_warn(dev,
+ "no such config option: %s\n", setting->name);
+ continue;
+ }
+
+ if (knob->reg + sizeof(u32) > resource_size(res)) {
+ dev_warn(dev,
+ "register offset of '%s' exceeds mapped memory size\n",
+ knob->name);
+ continue;
+ }
+
+ reg = readl(ddrctl + knob->reg);
+ reg &= knob->mask;
+ reg |= setting->val << knob->shift;
+
+ dev_dbg(dev, "writing 0x%08x to %s\n", reg, setting->name);
+
+ writel(reg, ddrctl + knob->reg);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id da8xx_ddrctl_of_match[] = {
+ { .compatible = "ti,da850-ddr-controller", },
+ { },
+};
+
+static struct platform_driver da8xx_ddrctl_driver = {
+ .probe = da8xx_ddrctl_probe,
+ .driver = {
+ .name = "da850-ddr-controller",
+ .of_match_table = da8xx_ddrctl_of_match,
+ },
+};
+module_platform_driver(da8xx_ddrctl_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx DDR2/mDDR controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 25e1aafae60c..227b99018657 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -1132,8 +1132,7 @@ static int pm860x_dt_init(struct device_node *np,
return 0;
}
-static int pm860x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int pm860x_probe(struct i2c_client *client)
{
struct pm860x_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *node = client->dev.of_node;
@@ -1259,7 +1258,7 @@ static struct i2c_driver pm860x_driver = {
.pm = &pm860x_pm_ops,
.of_match_table = pm860x_dt_ids,
},
- .probe = pm860x_probe,
+ .probe_new = pm860x_probe,
.remove = pm860x_remove,
.id_table = pm860x_id_table,
};
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index f84b53d6ce50..b33ab8ce47ab 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -19,12 +19,17 @@
*/
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/genalloc.h>
#include <linux/io.h>
#include <linux/list_sort.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <soc/at91/atmel-secumod.h>
#define SRAM_GRANULARITY 32
@@ -334,12 +339,33 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
return ret;
}
+static int atmel_securam_wait(void)
+{
+ struct regmap *regmap;
+ u32 val;
+
+ regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-secumod");
+ if (IS_ERR(regmap))
+ return -ENODEV;
+
+ return regmap_read_poll_timeout(regmap, AT91_SECUMOD_RAMRDY, val,
+ val & AT91_SECUMOD_RAMRDY_READY,
+ 10000, 500000);
+}
+
+static const struct of_device_id sram_dt_ids[] = {
+ { .compatible = "mmio-sram" },
+ { .compatible = "atmel,sama5d2-securam", .data = atmel_securam_wait },
+ {}
+};
+
static int sram_probe(struct platform_device *pdev)
{
struct sram_dev *sram;
struct resource *res;
size_t size;
int ret;
+ int (*init_func)(void);
sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
if (!sram)
@@ -384,6 +410,13 @@ static int sram_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sram);
+ init_func = of_device_get_match_data(&pdev->dev);
+ if (init_func) {
+ ret = init_func();
+ if (ret)
+ return ret;
+ }
+
dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
gen_pool_size(sram->pool) / 1024, sram->virt_base);
@@ -405,17 +438,10 @@ static int sram_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_OF
-static const struct of_device_id sram_dt_ids[] = {
- { .compatible = "mmio-sram" },
- {}
-};
-#endif
-
static struct platform_driver sram_driver = {
.driver = {
.name = "sram",
- .of_match_table = of_match_ptr(sram_dt_ids),
+ .of_match_table = sram_dt_ids,
},
.probe = sram_probe,
.remove = sram_remove,
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 75d07fa9d0b1..b2ca8a635b2e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -4020,49 +4020,51 @@ int mlx4_restart_one(struct pci_dev *pdev)
return err;
}
+#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT }
+#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF }
+#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 }
+
static const struct pci_device_id mlx4_pci_table[] = {
- /* MT25408 "Hermon" SDR */
- { PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25408 "Hermon" DDR */
- { PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25408 "Hermon" QDR */
- { PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25408 "Hermon" DDR PCIe gen2 */
- { PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25408 "Hermon" QDR PCIe gen2 */
- { PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25408 "Hermon" EN 10GigE */
- { PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25408 "Hermon" EN 10GigE PCIe gen2 */
- { PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25458 ConnectX EN 10GBASE-T 10GigE */
- { PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
- { PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT26468 ConnectX EN 10GigE PCIe gen2*/
- { PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */
- { PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT26478 ConnectX2 40GigE PCIe gen2 */
- { PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT },
- /* MT25400 Family [ConnectX-2 Virtual Function] */
- { PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF },
+ /* MT25408 "Hermon" */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_SDR), /* SDR */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR), /* DDR */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR), /* QDR */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2), /* DDR Gen2 */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2), /* QDR Gen2 */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN), /* EN 10GigE */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2), /* EN 10GigE Gen2 */
+ /* MT25458 ConnectX EN 10GBASE-T */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN),
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2), /* Gen2 */
+ /* MT26468 ConnectX EN 10GigE PCIe Gen2*/
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2),
+ /* MT26438 ConnectX EN 40GigE PCIe Gen2 5GT/s */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2),
+ /* MT26478 ConnectX2 40GigE PCIe Gen2 */
+ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX2),
+ /* MT25400 Family [ConnectX-2] */
+ MLX_VF(0x1002), /* Virtual Function */
/* MT27500 Family [ConnectX-3] */
- { PCI_VDEVICE(MELLANOX, 0x1003), 0 },
- /* MT27500 Family [ConnectX-3 Virtual Function] */
- { PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF },
- { PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */
- { PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */
- { PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */
- { PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */
- { PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */
- { PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */
- { PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */
- { PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */
- { PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */
- { PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */
- { PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */
- { PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */
+ MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3),
+ MLX_VF(0x1004), /* Virtual Function */
+ MLX_GN(0x1005), /* MT27510 Family */
+ MLX_GN(0x1006), /* MT27511 Family */
+ MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO), /* MT27520 Family */
+ MLX_GN(0x1008), /* MT27521 Family */
+ MLX_GN(0x1009), /* MT27530 Family */
+ MLX_GN(0x100a), /* MT27531 Family */
+ MLX_GN(0x100b), /* MT27540 Family */
+ MLX_GN(0x100c), /* MT27541 Family */
+ MLX_GN(0x100d), /* MT27550 Family */
+ MLX_GN(0x100e), /* MT27551 Family */
+ MLX_GN(0x100f), /* MT27560 Family */
+ MLX_GN(0x1010), /* MT27561 Family */
+
+ /*
+ * See the mellanox_check_broken_intx_masking() quirk when
+ * adding devices
+ */
+
{ 0, }
};
diff --git a/drivers/net/ethernet/qlogic/qede/qede_roce.c b/drivers/net/ethernet/qlogic/qede/qede_roce.c
index 9867f960b063..49272716a7c4 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_roce.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_roce.c
@@ -191,8 +191,8 @@ int qede_roce_register_driver(struct qedr_driver *drv)
}
mutex_unlock(&qedr_dev_list_lock);
- DP_INFO(edev, "qedr: discovered and registered %d RoCE funcs\n",
- qedr_counter);
+ pr_notice("qedr: discovered and registered %d RoCE funcs\n",
+ qedr_counter);
return 0;
}
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 7dc37a090549..59e077be8829 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -119,9 +119,8 @@ enum {
};
/*
- * PCI vendor and device IDs.
+ * Maximum devices supported.
*/
-#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
#define MAX_ETHERNET_CARDS 10
#define MAX_PCI_PASSTHRU_DEVICE 6
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index f42ab70ffa38..f587af345889 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -42,6 +42,28 @@
#define NVME_RDMA_MAX_INLINE_SEGMENTS 1
+static const char *const nvme_rdma_cm_status_strs[] = {
+ [NVME_RDMA_CM_INVALID_LEN] = "invalid length",
+ [NVME_RDMA_CM_INVALID_RECFMT] = "invalid record format",
+ [NVME_RDMA_CM_INVALID_QID] = "invalid queue ID",
+ [NVME_RDMA_CM_INVALID_HSQSIZE] = "invalid host SQ size",
+ [NVME_RDMA_CM_INVALID_HRQSIZE] = "invalid host RQ size",
+ [NVME_RDMA_CM_NO_RSC] = "resource not found",
+ [NVME_RDMA_CM_INVALID_IRD] = "invalid IRD",
+ [NVME_RDMA_CM_INVALID_ORD] = "Invalid ORD",
+};
+
+static const char *nvme_rdma_cm_msg(enum nvme_rdma_cm_status status)
+{
+ size_t index = status;
+
+ if (index < ARRAY_SIZE(nvme_rdma_cm_status_strs) &&
+ nvme_rdma_cm_status_strs[index])
+ return nvme_rdma_cm_status_strs[index];
+ else
+ return "unrecognized reason";
+};
+
/*
* We handle AEN commands ourselves and don't even let the
* block layer know about them.
@@ -1214,16 +1236,24 @@ out_destroy_queue_ib:
static int nvme_rdma_conn_rejected(struct nvme_rdma_queue *queue,
struct rdma_cm_event *ev)
{
- if (ev->param.conn.private_data_len) {
- struct nvme_rdma_cm_rej *rej =
- (struct nvme_rdma_cm_rej *)ev->param.conn.private_data;
+ struct rdma_cm_id *cm_id = queue->cm_id;
+ int status = ev->status;
+ const char *rej_msg;
+ const struct nvme_rdma_cm_rej *rej_data;
+ u8 rej_data_len;
+
+ rej_msg = rdma_reject_msg(cm_id, status);
+ rej_data = rdma_consumer_reject_data(cm_id, ev, &rej_data_len);
+
+ if (rej_data && rej_data_len >= sizeof(u16)) {
+ u16 sts = le16_to_cpu(rej_data->sts);
dev_err(queue->ctrl->ctrl.device,
- "Connect rejected, status %d.", le16_to_cpu(rej->sts));
- /* XXX: Think of something clever to do here... */
+ "Connect rejected: status %d (%s) nvme status %d (%s).\n",
+ status, rej_msg, sts, nvme_rdma_cm_msg(sts));
} else {
dev_err(queue->ctrl->ctrl.device,
- "Connect rejected, no private data.\n");
+ "Connect rejected: status %d (%s).\n", status, rej_msg);
}
return -ECONNRESET;
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 3fbcdb7a583c..8c3760a78ac0 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -1374,6 +1374,9 @@ static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id,
ret = nvmet_rdma_device_removal(cm_id, queue);
break;
case RDMA_CM_EVENT_REJECTED:
+ pr_debug("Connection rejected: %s\n",
+ rdma_reject_msg(cm_id, event->status));
+ /* FALLTHROUGH */
case RDMA_CM_EVENT_UNREACHABLE:
case RDMA_CM_EVENT_CONNECT_ERROR:
nvmet_rdma_queue_connect_fail(cm_id, queue);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a0bccb54a9bd..d4bea3c797d6 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1534,9 +1534,12 @@ void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
{
int i;
printk("%s %s", msg, of_node_full_name(args->np));
- for (i = 0; i < args->args_count; i++)
- printk(i ? ",%08x" : ":%08x", args->args[i]);
- printk("\n");
+ for (i = 0; i < args->args_count; i++) {
+ const char delim = i ? ',' : ':';
+
+ pr_cont("%c%08x", delim, args->args[i]);
+ }
+ pr_cont("\n");
}
int of_phandle_iterator_init(struct of_phandle_iterator *it,
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 393fea85eb4e..3fda9a32defb 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -697,3 +697,4 @@ void of_msi_configure(struct device *dev, struct device_node *np)
dev_set_msi_domain(dev,
of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
}
+EXPORT_SYMBOL_GPL(of_msi_configure);
diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c
index f63d4b0deff0..a53982a330ea 100644
--- a/drivers/of/of_numa.c
+++ b/drivers/of/of_numa.c
@@ -176,7 +176,12 @@ int of_node_to_nid(struct device_node *device)
np->name);
of_node_put(np);
- if (!r)
+ /*
+ * If numa=off passed on command line, or with a defective
+ * device tree, the nid may not be in the set of possible
+ * nodes. Check for this case and return NUMA_NO_NODE.
+ */
+ if (!r && nid < MAX_NUMNODES && node_possible(nid))
return nid;
return NUMA_NO_NODE;
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index b58be12ab277..0ee42c3e66a1 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -120,6 +120,27 @@ int of_get_pci_domain_nr(struct device_node *node)
EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
/**
+ * This function will try to find the limitation of link speed by finding
+ * a property called "max-link-speed" of the given device node.
+ *
+ * @node: device tree node with the max link speed information
+ *
+ * Returns the associated max link speed from DT, or a negative value if the
+ * required property is not found or is invalid.
+ */
+int of_pci_get_max_link_speed(struct device_node *node)
+{
+ u32 max_link_speed;
+
+ if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
+ max_link_speed > 4)
+ return -EINVAL;
+
+ return max_link_speed;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
+
+/**
* of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
* is present and valid
*/
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index e4bf07d20f9b..b8064bc2b6eb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -45,6 +45,9 @@ static int of_dev_node_match(struct device *dev, void *data)
* of_find_device_by_node - Find the platform_device associated with a node
* @np: Pointer to device tree node
*
+ * Takes a reference to the embedded struct device which needs to be dropped
+ * after use.
+ *
* Returns platform_device pointer, or NULL if not found
*/
struct platform_device *of_find_device_by_node(struct device_node *np)
@@ -558,9 +561,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
* of the given device (and, recurrently, their children) that have been
* created from their respective device tree nodes (and only those,
* leaving others - eg. manually created - unharmed).
- *
- * Returns 0 when all children devices have been removed or
- * -EBUSY when some children remained.
*/
void of_platform_depopulate(struct device *parent)
{
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 46325d6394cf..8bf12e904fd2 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -28,20 +28,19 @@
* Find a node with the give full name by recursively following any of
* the child node links.
*/
-static struct device_node *__of_find_node_by_full_name(struct device_node *node,
+static struct device_node *find_node_by_full_name(struct device_node *node,
const char *full_name)
{
struct device_node *child, *found;
- if (node == NULL)
+ if (!node)
return NULL;
- /* check */
- if (of_node_cmp(node->full_name, full_name) == 0)
+ if (!of_node_cmp(node->full_name, full_name))
return of_node_get(node);
for_each_child_of_node(node, child) {
- found = __of_find_node_by_full_name(child, full_name);
+ found = find_node_by_full_name(child, full_name);
if (found != NULL) {
of_node_put(child);
return found;
@@ -51,16 +50,12 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node,
return NULL;
}
-/*
- * Find live tree's maximum phandle value.
- */
-static phandle of_get_tree_max_phandle(void)
+static phandle live_tree_max_phandle(void)
{
struct device_node *node;
phandle phandle;
unsigned long flags;
- /* now search recursively */
raw_spin_lock_irqsave(&devtree_lock, flags);
phandle = 0;
for_each_of_allnodes(node) {
@@ -73,131 +68,102 @@ static phandle of_get_tree_max_phandle(void)
return phandle;
}
-/*
- * Adjust a subtree's phandle values by a given delta.
- * Makes sure not to just adjust the device node's phandle value,
- * but modify the phandle properties values as well.
- */
-static void __of_adjust_tree_phandles(struct device_node *node,
+static void adjust_overlay_phandles(struct device_node *overlay,
int phandle_delta)
{
struct device_node *child;
struct property *prop;
phandle phandle;
- /* first adjust the node's phandle direct value */
- if (node->phandle != 0 && node->phandle != OF_PHANDLE_ILLEGAL)
- node->phandle += phandle_delta;
+ /* adjust node's phandle in node */
+ if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
+ overlay->phandle += phandle_delta;
- /* now adjust phandle & linux,phandle values */
- for_each_property_of_node(node, prop) {
+ /* copy adjusted phandle into *phandle properties */
+ for_each_property_of_node(overlay, prop) {
- /* only look for these two */
- if (of_prop_cmp(prop->name, "phandle") != 0 &&
- of_prop_cmp(prop->name, "linux,phandle") != 0)
+ if (of_prop_cmp(prop->name, "phandle") &&
+ of_prop_cmp(prop->name, "linux,phandle"))
continue;
- /* must be big enough */
if (prop->length < 4)
continue;
- /* read phandle value */
phandle = be32_to_cpup(prop->value);
- if (phandle == OF_PHANDLE_ILLEGAL) /* unresolved */
+ if (phandle == OF_PHANDLE_ILLEGAL)
continue;
- /* adjust */
- *(uint32_t *)prop->value = cpu_to_be32(node->phandle);
+ *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
}
- /* now do the children recursively */
- for_each_child_of_node(node, child)
- __of_adjust_tree_phandles(child, phandle_delta);
+ for_each_child_of_node(overlay, child)
+ adjust_overlay_phandles(child, phandle_delta);
}
-static int __of_adjust_phandle_ref(struct device_node *node,
- struct property *rprop, int value)
+static int update_usages_of_a_phandle_reference(struct device_node *overlay,
+ struct property *prop_fixup, phandle phandle)
{
- phandle phandle;
struct device_node *refnode;
- struct property *sprop;
- char *propval, *propcur, *propend, *nodestr, *propstr, *s;
- int offset, propcurlen;
+ struct property *prop;
+ char *value, *cur, *end, *node_path, *prop_name, *s;
+ int offset, len;
int err = 0;
- /* make a copy */
- propval = kmalloc(rprop->length, GFP_KERNEL);
- if (!propval) {
- pr_err("%s: Could not copy value of '%s'\n",
- __func__, rprop->name);
+ value = kmalloc(prop_fixup->length, GFP_KERNEL);
+ if (!value)
return -ENOMEM;
- }
- memcpy(propval, rprop->value, rprop->length);
+ memcpy(value, prop_fixup->value, prop_fixup->length);
- propend = propval + rprop->length;
- for (propcur = propval; propcur < propend; propcur += propcurlen + 1) {
- propcurlen = strlen(propcur);
+ /* prop_fixup contains a list of tuples of path:property_name:offset */
+ end = value + prop_fixup->length;
+ for (cur = value; cur < end; cur += len + 1) {
+ len = strlen(cur);
- nodestr = propcur;
- s = strchr(propcur, ':');
+ node_path = cur;
+ s = strchr(cur, ':');
if (!s) {
- pr_err("%s: Illegal symbol entry '%s' (1)\n",
- __func__, propcur);
err = -EINVAL;
goto err_fail;
}
*s++ = '\0';
- propstr = s;
+ prop_name = s;
s = strchr(s, ':');
if (!s) {
- pr_err("%s: Illegal symbol entry '%s' (2)\n",
- __func__, (char *)rprop->value);
err = -EINVAL;
goto err_fail;
}
-
*s++ = '\0';
+
err = kstrtoint(s, 10, &offset);
- if (err != 0) {
- pr_err("%s: Could get offset '%s'\n",
- __func__, (char *)rprop->value);
+ if (err)
goto err_fail;
- }
- /* look into the resolve node for the full path */
- refnode = __of_find_node_by_full_name(node, nodestr);
- if (!refnode) {
- pr_warn("%s: Could not find refnode '%s'\n",
- __func__, (char *)rprop->value);
+ refnode = find_node_by_full_name(overlay, node_path);
+ if (!refnode)
continue;
- }
- /* now find the property */
- for_each_property_of_node(refnode, sprop) {
- if (of_prop_cmp(sprop->name, propstr) == 0)
+ for_each_property_of_node(refnode, prop) {
+ if (!of_prop_cmp(prop->name, prop_name))
break;
}
of_node_put(refnode);
- if (!sprop) {
- pr_err("%s: Could not find property '%s'\n",
- __func__, (char *)rprop->value);
+ if (!prop) {
err = -ENOENT;
goto err_fail;
}
- phandle = value;
- *(__be32 *)(sprop->value + offset) = cpu_to_be32(phandle);
+ *(__be32 *)(prop->value + offset) = cpu_to_be32(phandle);
}
err_fail:
- kfree(propval);
+ kfree(value);
return err;
}
/* compare nodes taking into account that 'name' strips out the @ part */
-static int __of_node_name_cmp(const struct device_node *dn1,
+static int node_name_cmp(const struct device_node *dn1,
const struct device_node *dn2)
{
const char *n1 = strrchr(dn1->full_name, '/') ? : "/";
@@ -208,85 +174,77 @@ static int __of_node_name_cmp(const struct device_node *dn1,
/*
* Adjust the local phandle references by the given phandle delta.
- * Assumes the existances of a __local_fixups__ node at the root.
- * Assumes that __of_verify_tree_phandle_references has been called.
- * Does not take any devtree locks so make sure you call this on a tree
- * which is at the detached state.
+ *
+ * Subtree @local_fixups, which is overlay node __local_fixups__,
+ * mirrors the fragment node structure at the root of the overlay.
+ *
+ * For each property in the fragments that contains a phandle reference,
+ * @local_fixups has a property of the same name that contains a list
+ * of offsets of the phandle reference(s) within the respective property
+ * value(s). The values at these offsets will be fixed up.
*/
-static int __of_adjust_tree_phandle_references(struct device_node *node,
- struct device_node *target, int phandle_delta)
+static int adjust_local_phandle_references(struct device_node *local_fixups,
+ struct device_node *overlay, int phandle_delta)
{
- struct device_node *child, *childtarget;
- struct property *rprop, *sprop;
+ struct device_node *child, *overlay_child;
+ struct property *prop_fix, *prop;
int err, i, count;
unsigned int off;
phandle phandle;
- if (node == NULL)
+ if (!local_fixups)
return 0;
- for_each_property_of_node(node, rprop) {
+ for_each_property_of_node(local_fixups, prop_fix) {
/* skip properties added automatically */
- if (of_prop_cmp(rprop->name, "name") == 0 ||
- of_prop_cmp(rprop->name, "phandle") == 0 ||
- of_prop_cmp(rprop->name, "linux,phandle") == 0)
+ if (!of_prop_cmp(prop_fix->name, "name") ||
+ !of_prop_cmp(prop_fix->name, "phandle") ||
+ !of_prop_cmp(prop_fix->name, "linux,phandle"))
continue;
- if ((rprop->length % 4) != 0 || rprop->length == 0) {
- pr_err("%s: Illegal property (size) '%s' @%s\n",
- __func__, rprop->name, node->full_name);
+ if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
return -EINVAL;
- }
- count = rprop->length / sizeof(__be32);
+ count = prop_fix->length / sizeof(__be32);
- /* now find the target property */
- for_each_property_of_node(target, sprop) {
- if (of_prop_cmp(sprop->name, rprop->name) == 0)
+ for_each_property_of_node(overlay, prop) {
+ if (!of_prop_cmp(prop->name, prop_fix->name))
break;
}
- if (sprop == NULL) {
- pr_err("%s: Could not find target property '%s' @%s\n",
- __func__, rprop->name, node->full_name);
+ if (!prop)
return -EINVAL;
- }
for (i = 0; i < count; i++) {
- off = be32_to_cpu(((__be32 *)rprop->value)[i]);
- /* make sure the offset doesn't overstep (even wrap) */
- if (off >= sprop->length ||
- (off + 4) > sprop->length) {
- pr_err("%s: Illegal property '%s' @%s\n",
- __func__, rprop->name,
- node->full_name);
+ off = be32_to_cpu(((__be32 *)prop_fix->value)[i]);
+ if ((off + 4) > prop->length)
return -EINVAL;
- }
-
- if (phandle_delta) {
- /* adjust */
- phandle = be32_to_cpu(*(__be32 *)(sprop->value + off));
- phandle += phandle_delta;
- *(__be32 *)(sprop->value + off) = cpu_to_be32(phandle);
- }
+
+ phandle = be32_to_cpu(*(__be32 *)(prop->value + off));
+ phandle += phandle_delta;
+ *(__be32 *)(prop->value + off) = cpu_to_be32(phandle);
}
}
- for_each_child_of_node(node, child) {
-
- for_each_child_of_node(target, childtarget)
- if (__of_node_name_cmp(child, childtarget) == 0)
+ /*
+ * These nested loops recurse down two subtrees in parallel, where the
+ * node names in the two subtrees match.
+ *
+ * The roots of the subtrees are the overlay's __local_fixups__ node
+ * and the overlay's root node.
+ */
+ for_each_child_of_node(local_fixups, child) {
+
+ for_each_child_of_node(overlay, overlay_child)
+ if (!node_name_cmp(child, overlay_child))
break;
- if (!childtarget) {
- pr_err("%s: Could not find target child '%s' @%s\n",
- __func__, child->name, node->full_name);
+ if (!overlay_child)
return -EINVAL;
- }
- err = __of_adjust_tree_phandle_references(child, childtarget,
+ err = adjust_local_phandle_references(child, overlay_child,
phandle_delta);
- if (err != 0)
+ if (err)
return err;
}
@@ -294,111 +252,103 @@ static int __of_adjust_tree_phandle_references(struct device_node *node,
}
/**
- * of_resolve - Resolve the given node against the live tree.
+ * of_resolve_phandles - Relocate and resolve overlay against live tree
*
- * @resolve: Node to resolve
+ * @overlay: Pointer to devicetree overlay to relocate and resolve
*
- * Perform dynamic Device Tree resolution against the live tree
- * to the given node to resolve. This depends on the live tree
- * having a __symbols__ node, and the resolve node the __fixups__ &
- * __local_fixups__ nodes (if needed).
- * The result of the operation is a resolve node that it's contents
- * are fit to be inserted or operate upon the live tree.
- * Returns 0 on success or a negative error value on error.
+ * Modify (relocate) values of local phandles in @overlay to a range that
+ * does not conflict with the live expanded devicetree. Update references
+ * to the local phandles in @overlay. Update (resolve) phandle references
+ * in @overlay that refer to the live expanded devicetree.
+ *
+ * Phandle values in the live tree are in the range of
+ * 1 .. live_tree_max_phandle(). The range of phandle values in the overlay
+ * also begin with at 1. Adjust the phandle values in the overlay to begin
+ * at live_tree_max_phandle() + 1. Update references to the phandles to
+ * the adjusted phandle values.
+ *
+ * The name of each property in the "__fixups__" node in the overlay matches
+ * the name of a symbol (a label) in the live tree. The values of each
+ * property in the "__fixups__" node is a list of the property values in the
+ * overlay that need to be updated to contain the phandle reference
+ * corresponding to that symbol in the live tree. Update the references in
+ * the overlay with the phandle values in the live tree.
+ *
+ * @overlay must be detached.
+ *
+ * Resolving and applying @overlay to the live expanded devicetree must be
+ * protected by a mechanism to ensure that multiple overlays are processed
+ * in a single threaded manner so that multiple overlays will not relocate
+ * phandles to overlapping ranges. The mechanism to enforce this is not
+ * yet implemented.
+ *
+ * Return: %0 on success or a negative error value on error.
*/
-int of_resolve_phandles(struct device_node *resolve)
+int of_resolve_phandles(struct device_node *overlay)
{
- struct device_node *child, *childroot, *refnode;
- struct device_node *root_sym, *resolve_sym, *resolve_fix;
- struct property *rprop;
+ struct device_node *child, *local_fixups, *refnode;
+ struct device_node *tree_symbols, *overlay_fixups;
+ struct property *prop;
const char *refpath;
phandle phandle, phandle_delta;
int err;
- if (!resolve)
- pr_err("%s: null node\n", __func__);
- if (resolve && !of_node_check_flag(resolve, OF_DETACHED))
- pr_err("%s: node %s not detached\n", __func__,
- resolve->full_name);
- /* the resolve node must exist, and be detached */
- if (!resolve || !of_node_check_flag(resolve, OF_DETACHED))
- return -EINVAL;
-
- /* first we need to adjust the phandles */
- phandle_delta = of_get_tree_max_phandle() + 1;
- __of_adjust_tree_phandles(resolve, phandle_delta);
-
- /* locate the local fixups */
- childroot = NULL;
- for_each_child_of_node(resolve, childroot)
- if (of_node_cmp(childroot->name, "__local_fixups__") == 0)
- break;
-
- if (childroot != NULL) {
- /* resolve root is guaranteed to be the '/' */
- err = __of_adjust_tree_phandle_references(childroot,
- resolve, 0);
- if (err != 0)
- return err;
+ tree_symbols = NULL;
- BUG_ON(__of_adjust_tree_phandle_references(childroot,
- resolve, phandle_delta));
+ if (!overlay) {
+ pr_err("null overlay\n");
+ err = -EINVAL;
+ goto out;
+ }
+ if (!of_node_check_flag(overlay, OF_DETACHED)) {
+ pr_err("overlay not detached\n");
+ err = -EINVAL;
+ goto out;
}
- root_sym = NULL;
- resolve_sym = NULL;
- resolve_fix = NULL;
-
- /* this may fail (if no fixups are required) */
- root_sym = of_find_node_by_path("/__symbols__");
+ phandle_delta = live_tree_max_phandle() + 1;
+ adjust_overlay_phandles(overlay, phandle_delta);
- /* locate the symbols & fixups nodes on resolve */
- for_each_child_of_node(resolve, child) {
+ for_each_child_of_node(overlay, local_fixups)
+ if (!of_node_cmp(local_fixups->name, "__local_fixups__"))
+ break;
- if (!resolve_sym &&
- of_node_cmp(child->name, "__symbols__") == 0)
- resolve_sym = child;
+ err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
+ if (err)
+ goto out;
- if (!resolve_fix &&
- of_node_cmp(child->name, "__fixups__") == 0)
- resolve_fix = child;
+ overlay_fixups = NULL;
- /* both found, don't bother anymore */
- if (resolve_sym && resolve_fix)
- break;
+ for_each_child_of_node(overlay, child) {
+ if (!of_node_cmp(child->name, "__fixups__"))
+ overlay_fixups = child;
}
- /* we do allow for the case where no fixups are needed */
- if (!resolve_fix) {
- err = 0; /* no error */
+ if (!overlay_fixups) {
+ err = 0;
goto out;
}
- /* we need to fixup, but no root symbols... */
- if (!root_sym) {
- pr_err("%s: no symbols in root of device tree.\n", __func__);
+ tree_symbols = of_find_node_by_path("/__symbols__");
+ if (!tree_symbols) {
+ pr_err("no symbols in root of device tree.\n");
err = -EINVAL;
goto out;
}
- for_each_property_of_node(resolve_fix, rprop) {
+ for_each_property_of_node(overlay_fixups, prop) {
/* skip properties added automatically */
- if (of_prop_cmp(rprop->name, "name") == 0)
+ if (!of_prop_cmp(prop->name, "name"))
continue;
- err = of_property_read_string(root_sym,
- rprop->name, &refpath);
- if (err != 0) {
- pr_err("%s: Could not find symbol '%s'\n",
- __func__, rprop->name);
+ err = of_property_read_string(tree_symbols,
+ prop->name, &refpath);
+ if (err)
goto out;
- }
refnode = of_find_node_by_path(refpath);
if (!refnode) {
- pr_err("%s: Could not find node by path '%s'\n",
- __func__, refpath);
err = -ENOENT;
goto out;
}
@@ -406,17 +356,15 @@ int of_resolve_phandles(struct device_node *resolve)
phandle = refnode->phandle;
of_node_put(refnode);
- pr_debug("%s: %s phandle is 0x%08x\n",
- __func__, rprop->name, phandle);
-
- err = __of_adjust_phandle_ref(resolve, rprop, phandle);
+ err = update_usages_of_a_phandle_reference(overlay, prop, phandle);
if (err)
break;
}
out:
- /* NULL is handled by of_node_put as NOP */
- of_node_put(root_sym);
+ if (err)
+ pr_err("overlay phandle fixup failed: %d\n", err);
+ of_node_put(tree_symbols);
return err;
}
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index d11cdbb8fba3..db239547fefd 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -142,10 +142,22 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn,
if (size == 4) {
writel(val, addr);
return PCIBIOS_SUCCESSFUL;
- } else {
- mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
}
+ /*
+ * In general, hardware that supports only 32-bit writes on PCI is
+ * not spec-compliant. For example, software may perform a 16-bit
+ * write. If the hardware only supports 32-bit accesses, we must
+ * do a 32-bit read, merge in the 16 bits we intend to write,
+ * followed by a 32-bit write. If the 16 bits we *don't* intend to
+ * write happen to have any RW1C (write-one-to-clear) bits set, we
+ * just inadvertently cleared something we shouldn't have.
+ */
+ dev_warn_ratelimited(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n",
+ size, pci_domain_nr(bus), bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where);
+
+ mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
tmp = readl(addr) & mask;
tmp |= val << ((where & 0x3) * 8);
writel(tmp, addr);
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index c288e5a52575..bc56cf19afd3 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -320,7 +320,7 @@ void pci_bus_add_device(struct pci_dev *dev)
pci_fixup_device(pci_fixup_final, dev);
pci_create_sysfs_dev_files(dev);
pci_proc_attach_device(dev);
- pci_bridge_d3_device_changed(dev);
+ pci_bridge_d3_update(dev);
dev->match_driver = true;
retval = device_attach(&dev->dev);
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index 43ed08dd8b01..2fee61bb6559 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -162,3 +162,15 @@ struct pci_ecam_ops pci_generic_ecam_ops = {
.write = pci_generic_config_write,
}
};
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
+/* ECAM ops for 32-bit access only (non-compliant) */
+struct pci_ecam_ops pci_32b_ops = {
+ .bus_shift = 20,
+ .pci_ops = {
+ .map_bus = pci_ecam_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
+ }
+};
+#endif
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index d7e7c0a827c3..898d2c48239c 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -69,7 +69,7 @@ config PCI_IMX6
config PCI_TEGRA
bool "NVIDIA Tegra PCIe controller"
- depends on ARCH_TEGRA && !ARM64
+ depends on ARCH_TEGRA
help
Say Y here if you want support for the PCIe host controller found
on NVIDIA Tegra SoCs.
@@ -133,8 +133,8 @@ config PCIE_XILINX
config PCI_XGENE
bool "X-Gene PCIe controller"
- depends on ARCH_XGENE
- depends on OF
+ depends on ARM64
+ depends on OF || (ACPI && PCI_QUIRKS)
select PCIEPORTBUS
help
Say Y here if you want internal PCI support on APM X-Gene SoC.
@@ -240,14 +240,16 @@ config PCIE_QCOM
config PCI_HOST_THUNDER_PEM
bool "Cavium Thunder PCIe controller to off-chip devices"
- depends on OF && ARM64
+ depends on ARM64
+ depends on OF || (ACPI && PCI_QUIRKS)
select PCI_HOST_COMMON
help
Say Y here if you want PCIe support for CN88XX Cavium Thunder SoCs.
config PCI_HOST_THUNDER_ECAM
bool "Cavium Thunder ECAM controller to on-chip devices on pass-1.x silicon"
- depends on OF && ARM64
+ depends on ARM64
+ depends on OF || (ACPI && PCI_QUIRKS)
select PCI_HOST_COMMON
help
Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
@@ -276,7 +278,7 @@ config PCIE_ARTPEC6
config PCIE_ROCKCHIP
bool "Rockchip PCIe controller"
- depends on ARCH_ROCKCHIP
+ depends on ARCH_ROCKCHIP || COMPILE_TEST
depends on OF
depends on PCI_MSI_IRQ_DOMAIN
select MFD_SYSCON
@@ -286,7 +288,7 @@ config PCIE_ROCKCHIP
4 slots.
config VMD
- depends on PCI_MSI && X86_64
+ depends on PCI_MSI && X86_64 && SRCU
tristate "Intel Volume Management Device Driver"
default N
---help---
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb4983645..bfe3179ae74c 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o
-obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
@@ -25,11 +24,23 @@ 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
-obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
-obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
obj-$(CONFIG_VMD) += vmd.o
+
+# The following drivers are for devices that use the generic ACPI
+# pci_root.c driver but don't support standard ECAM config access.
+# They contain MCFG quirks to replace the generic ECAM accessors with
+# device-specific ones that are shared with the DT driver.
+
+# The ACPI driver is generic and should not require driver-specific
+# config options to be enabled, so we always build these drivers on
+# ARM64 and use internal ifdefs to only build the pieces we need
+# depending on whether ACPI, the DT driver, or both are enabled.
+
+obj-$(CONFIG_ARM64) += pcie-hisi.o
+obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
+obj-$(CONFIG_ARM64) += pci-thunder-pem.o
+obj-$(CONFIG_ARM64) += pci-xgene.o
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 763ff8745828..3efcc7bdc5fb 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -378,6 +378,8 @@ struct hv_pcibus_device {
struct msi_domain_info msi_info;
struct msi_controller msi_chip;
struct irq_domain *irq_domain;
+ struct retarget_msi_interrupt retarget_msi_interrupt_params;
+ spinlock_t retarget_msi_interrupt_lock;
};
/*
@@ -755,7 +757,7 @@ static int hv_set_affinity(struct irq_data *data, const struct cpumask *dest,
return parent->chip->irq_set_affinity(parent, dest, force);
}
-void hv_irq_mask(struct irq_data *data)
+static void hv_irq_mask(struct irq_data *data)
{
pci_msi_mask_irq(data);
}
@@ -770,38 +772,44 @@ void hv_irq_mask(struct irq_data *data)
* is built out of this PCI bus's instance GUID and the function
* number of the device.
*/
-void hv_irq_unmask(struct irq_data *data)
+static void hv_irq_unmask(struct irq_data *data)
{
struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
struct irq_cfg *cfg = irqd_cfg(data);
- struct retarget_msi_interrupt params;
+ struct retarget_msi_interrupt *params;
struct hv_pcibus_device *hbus;
struct cpumask *dest;
struct pci_bus *pbus;
struct pci_dev *pdev;
int cpu;
+ unsigned long flags;
dest = irq_data_get_affinity_mask(data);
pdev = msi_desc_to_pci_dev(msi_desc);
pbus = pdev->bus;
hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
- memset(&params, 0, sizeof(params));
- params.partition_id = HV_PARTITION_ID_SELF;
- params.source = 1; /* MSI(-X) */
- params.address = msi_desc->msg.address_lo;
- params.data = msi_desc->msg.data;
- params.device_id = (hbus->hdev->dev_instance.b[5] << 24) |
+ spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags);
+
+ params = &hbus->retarget_msi_interrupt_params;
+ memset(params, 0, sizeof(*params));
+ params->partition_id = HV_PARTITION_ID_SELF;
+ params->source = 1; /* MSI(-X) */
+ params->address = msi_desc->msg.address_lo;
+ params->data = msi_desc->msg.data;
+ params->device_id = (hbus->hdev->dev_instance.b[5] << 24) |
(hbus->hdev->dev_instance.b[4] << 16) |
(hbus->hdev->dev_instance.b[7] << 8) |
(hbus->hdev->dev_instance.b[6] & 0xf8) |
PCI_FUNC(pdev->devfn);
- params.vector = cfg->vector;
+ params->vector = cfg->vector;
for_each_cpu_and(cpu, dest, cpu_online_mask)
- params.vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu));
+ params->vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu));
- hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, &params, NULL);
+ hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, params, NULL);
+
+ spin_unlock_irqrestore(&hbus->retarget_msi_interrupt_lock, flags);
pci_msi_unmask_irq(data);
}
@@ -1271,9 +1279,9 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus,
struct hv_pci_dev *hpdev;
struct pci_child_message *res_req;
struct q_res_req_compl comp_pkt;
- union {
- struct pci_packet init_packet;
- u8 buffer[0x100];
+ struct {
+ struct pci_packet init_packet;
+ u8 buffer[sizeof(struct pci_child_message)];
} pkt;
unsigned long flags;
int ret;
@@ -1582,6 +1590,10 @@ static void hv_eject_device_work(struct work_struct *work)
pci_dev_put(pdev);
}
+ spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags);
+ list_del(&hpdev->list_entry);
+ spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
+
memset(&ctxt, 0, sizeof(ctxt));
ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;
ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE;
@@ -1590,10 +1602,6 @@ static void hv_eject_device_work(struct work_struct *work)
sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt,
VM_PKT_DATA_INBAND, 0);
- spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags);
- list_del(&hpdev->list_entry);
- spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
-
put_pcichild(hpdev, hv_pcidev_ref_childlist);
put_pcichild(hpdev, hv_pcidev_ref_pnp);
put_hvpcibus(hpdev->hbus);
@@ -2186,6 +2194,7 @@ static int hv_pci_probe(struct hv_device *hdev,
INIT_LIST_HEAD(&hbus->resources_for_children);
spin_lock_init(&hbus->config_lock);
spin_lock_init(&hbus->device_list_lock);
+ spin_lock_init(&hbus->retarget_msi_interrupt_lock);
sema_init(&hbus->enum_sem, 1);
init_completion(&hbus->remove_event);
@@ -2266,24 +2275,32 @@ free_bus:
return ret;
}
-/**
- * hv_pci_remove() - Remove routine for this VMBus channel
- * @hdev: VMBus's tracking struct for this root PCI bus
- *
- * Return: 0 on success, -errno on failure
- */
-static int hv_pci_remove(struct hv_device *hdev)
+static void hv_pci_bus_exit(struct hv_device *hdev)
{
- int ret;
- struct hv_pcibus_device *hbus;
- union {
+ struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
+ struct {
struct pci_packet teardown_packet;
- u8 buffer[0x100];
+ u8 buffer[sizeof(struct pci_message)];
} pkt;
struct pci_bus_relations relations;
struct hv_pci_compl comp_pkt;
+ int ret;
- hbus = hv_get_drvdata(hdev);
+ /*
+ * After the host sends the RESCIND_CHANNEL message, it doesn't
+ * access the per-channel ringbuffer any longer.
+ */
+ if (hdev->channel->rescind)
+ return;
+
+ /* Delete any children which might still exist. */
+ memset(&relations, 0, sizeof(relations));
+ hv_pci_devices_present(hbus, &relations);
+
+ ret = hv_send_resources_released(hdev);
+ if (ret)
+ dev_err(&hdev->device,
+ "Couldn't send resources released packet(s)\n");
memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet));
init_completion(&comp_pkt.host_event);
@@ -2298,7 +2315,19 @@ static int hv_pci_remove(struct hv_device *hdev)
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (!ret)
wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ);
+}
+
+/**
+ * hv_pci_remove() - Remove routine for this VMBus channel
+ * @hdev: VMBus's tracking struct for this root PCI bus
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int hv_pci_remove(struct hv_device *hdev)
+{
+ struct hv_pcibus_device *hbus;
+ hbus = hv_get_drvdata(hdev);
if (hbus->state == hv_pcibus_installed) {
/* Remove the bus from PCI's point of view. */
pci_lock_rescan_remove();
@@ -2307,17 +2336,10 @@ static int hv_pci_remove(struct hv_device *hdev)
pci_unlock_rescan_remove();
}
- ret = hv_send_resources_released(hdev);
- if (ret)
- dev_err(&hdev->device,
- "Couldn't send resources released packet(s)\n");
+ hv_pci_bus_exit(hdev);
vmbus_close(hdev->channel);
- /* Delete any children which might still exist. */
- memset(&relations, 0, sizeof(relations));
- hv_pci_devices_present(hbus, &relations);
-
iounmap(hbus->cfg_addr);
hv_free_config_window(hbus);
pci_free_resource_list(&hbus->resources_for_children);
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index 653707996342..ea789138531b 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -35,12 +35,10 @@
#define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */
#define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */
-/* PEX LUT registers */
-#define PCIE_LUT_DBG 0x7FC /* PEX LUT Debug Register */
-
struct ls_pcie_drvdata {
u32 lut_offset;
u32 ltssm_shift;
+ u32 lut_dbg;
struct pcie_host_ops *ops;
};
@@ -134,7 +132,7 @@ static int ls_pcie_link_up(struct pcie_port *pp)
struct ls_pcie *pcie = to_ls_pcie(pp);
u32 state;
- state = (ioread32(pcie->lut + PCIE_LUT_DBG) >>
+ state = (ioread32(pcie->lut + pcie->drvdata->lut_dbg) >>
pcie->drvdata->ltssm_shift) &
LTSSM_STATE_MASK;
@@ -196,18 +194,28 @@ static struct ls_pcie_drvdata ls1021_drvdata = {
static struct ls_pcie_drvdata ls1043_drvdata = {
.lut_offset = 0x10000,
.ltssm_shift = 24,
+ .lut_dbg = 0x7fc,
+ .ops = &ls_pcie_host_ops,
+};
+
+static struct ls_pcie_drvdata ls1046_drvdata = {
+ .lut_offset = 0x80000,
+ .ltssm_shift = 24,
+ .lut_dbg = 0x407fc,
.ops = &ls_pcie_host_ops,
};
static struct ls_pcie_drvdata ls2080_drvdata = {
.lut_offset = 0x80000,
.ltssm_shift = 0,
+ .lut_dbg = 0x7fc,
.ops = &ls_pcie_host_ops,
};
static const struct of_device_id ls_pcie_of_match[] = {
{ .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata },
{ .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata },
+ { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata },
{ .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata },
{ .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata },
{ },
@@ -252,10 +260,8 @@ static int __init ls_pcie_probe(struct platform_device *pdev)
dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
pcie->pp.dbi_base = devm_ioremap_resource(dev, dbi_base);
- if (IS_ERR(pcie->pp.dbi_base)) {
- dev_err(dev, "missing *regs* space\n");
+ if (IS_ERR(pcie->pp.dbi_base))
return PTR_ERR(pcie->pp.dbi_base);
- }
pcie->lut = pcie->pp.dbi_base + pcie->drvdata->lut_offset;
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index 1eeefa4df64c..85348590848b 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -430,10 +430,10 @@ 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", },
+ { .compatible = "renesas,pci-rcar-gen2", },
{ },
};
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 8dfccf733241..ed8a93f2bfb5 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -51,10 +51,6 @@
#include <soc/tegra/cpuidle.h>
#include <soc/tegra/pmc.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/map.h>
-#include <asm/mach/pci.h>
-
#define INT_PCI_MSI_NR (8 * 32)
/* register definitions */
@@ -188,6 +184,9 @@
#define RP_VEND_XP 0x00000f00
#define RP_VEND_XP_DL_UP (1 << 30)
+#define RP_VEND_CTL2 0x00000fa8
+#define RP_VEND_CTL2_PCA_ENABLE (1 << 7)
+
#define RP_PRIV_MISC 0x00000fe0
#define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
#define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
@@ -252,6 +251,7 @@ struct tegra_pcie_soc {
bool has_intr_prsnt_sense;
bool has_cml_clk;
bool has_gen2;
+ bool force_pca_enable;
};
static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
@@ -322,11 +322,6 @@ struct tegra_pcie_bus {
unsigned int nr;
};
-static inline struct tegra_pcie *sys_to_pcie(struct pci_sys_data *sys)
-{
- return sys->private_data;
-}
-
static inline void afi_writel(struct tegra_pcie *pcie, u32 value,
unsigned long offset)
{
@@ -385,8 +380,7 @@ static struct tegra_pcie_bus *tegra_pcie_bus_alloc(struct tegra_pcie *pcie,
unsigned int busnr)
{
struct device *dev = pcie->dev;
- pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_XN | L_PTE_MT_DEV_SHARED | L_PTE_SHARED);
+ pgprot_t prot = pgprot_device(PAGE_KERNEL);
phys_addr_t cs = pcie->cs->start;
struct tegra_pcie_bus *bus;
unsigned int i;
@@ -430,7 +424,8 @@ free:
static int tegra_pcie_add_bus(struct pci_bus *bus)
{
- struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata);
+ struct pci_host_bridge *host = pci_find_host_bridge(bus);
+ struct tegra_pcie *pcie = pci_host_bridge_priv(host);
struct tegra_pcie_bus *b;
b = tegra_pcie_bus_alloc(pcie, bus->number);
@@ -444,7 +439,8 @@ static int tegra_pcie_add_bus(struct pci_bus *bus)
static void tegra_pcie_remove_bus(struct pci_bus *child)
{
- struct tegra_pcie *pcie = sys_to_pcie(child->sysdata);
+ struct pci_host_bridge *host = pci_find_host_bridge(child);
+ struct tegra_pcie *pcie = pci_host_bridge_priv(host);
struct tegra_pcie_bus *bus, *tmp;
list_for_each_entry_safe(bus, tmp, &pcie->buses, list) {
@@ -461,7 +457,8 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
unsigned int devfn,
int where)
{
- struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata);
+ struct pci_host_bridge *host = pci_find_host_bridge(bus);
+ struct tegra_pcie *pcie = pci_host_bridge_priv(host);
struct device *dev = pcie->dev;
void __iomem *addr = NULL;
@@ -558,6 +555,12 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
afi_writel(port->pcie, value, ctrl);
tegra_pcie_port_reset(port);
+
+ if (soc->force_pca_enable) {
+ value = readl(port->base + RP_VEND_CTL2);
+ value |= RP_VEND_CTL2_PCA_ENABLE;
+ writel(value, port->base + RP_VEND_CTL2);
+ }
}
static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
@@ -610,39 +613,31 @@ static void tegra_pcie_relax_enable(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
-static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
+static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
{
- struct tegra_pcie *pcie = sys_to_pcie(sys);
+ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
+ struct list_head *windows = &host->windows;
struct device *dev = pcie->dev;
int err;
- sys->mem_offset = pcie->offset.mem;
- sys->io_offset = pcie->offset.io;
+ pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
+ pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
+ pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
+ pci_add_resource(windows, &pcie->busn);
- err = devm_request_resource(dev, &iomem_resource, &pcie->io);
+ err = devm_request_pci_bus_resources(dev, windows);
if (err < 0)
return err;
- err = pci_remap_iospace(&pcie->pio, pcie->io.start);
- if (!err)
- pci_add_resource_offset(&sys->resources, &pcie->pio,
- sys->io_offset);
+ pci_remap_iospace(&pcie->pio, pcie->io.start);
- pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
- pci_add_resource_offset(&sys->resources, &pcie->prefetch,
- sys->mem_offset);
- pci_add_resource(&sys->resources, &pcie->busn);
-
- err = devm_request_pci_bus_resources(dev, &sys->resources);
- if (err < 0)
- return err;
-
- return 1;
+ return 0;
}
static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
- struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
+ struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
+ struct tegra_pcie *pcie = pci_host_bridge_priv(host);
int irq;
tegra_cpuidle_pcie_irqs_in_use();
@@ -1499,10 +1494,11 @@ static const struct irq_domain_ops msi_domain_ops = {
static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
{
- struct device *dev = pcie->dev;
- struct platform_device *pdev = to_platform_device(dev);
+ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
+ struct platform_device *pdev = to_platform_device(pcie->dev);
const struct tegra_pcie_soc *soc = pcie->soc;
struct tegra_msi *msi = &pcie->msi;
+ struct device *dev = pcie->dev;
unsigned long base;
int err;
u32 reg;
@@ -1559,6 +1555,8 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
reg |= AFI_INTR_MASK_MSI_MASK;
afi_writel(pcie, reg, AFI_INTR_MASK);
+ host->msi = &msi->chip;
+
return 0;
err:
@@ -1609,7 +1607,8 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
struct device *dev = pcie->dev;
struct device_node *np = dev->of_node;
- if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
+ if (of_device_is_compatible(np, "nvidia,tegra124-pcie") ||
+ of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
switch (lanes) {
case 0x0000104:
dev_info(dev, "4x1, 1x1 configuration\n");
@@ -1730,7 +1729,22 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
struct device_node *np = dev->of_node;
unsigned int i = 0;
- if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
+ if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
+ pcie->num_supplies = 6;
+
+ pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
+ sizeof(*pcie->supplies),
+ GFP_KERNEL);
+ if (!pcie->supplies)
+ return -ENOMEM;
+
+ pcie->supplies[i++].supply = "avdd-pll-uerefe";
+ pcie->supplies[i++].supply = "hvddio-pex";
+ pcie->supplies[i++].supply = "dvddio-pex";
+ pcie->supplies[i++].supply = "dvdd-pex-pll";
+ pcie->supplies[i++].supply = "hvdd-pex-pll-e";
+ pcie->supplies[i++].supply = "vddio-pex-ctl";
+ } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
pcie->num_supplies = 7;
pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
@@ -2021,11 +2035,10 @@ retry:
return false;
}
-static int tegra_pcie_enable(struct tegra_pcie *pcie)
+static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
{
struct device *dev = pcie->dev;
struct tegra_pcie_port *port, *tmp;
- struct hw_pci hw;
list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
dev_info(dev, "probing port %u, using %u lanes\n",
@@ -2041,21 +2054,6 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)
tegra_pcie_port_disable(port);
tegra_pcie_port_free(port);
}
-
- memset(&hw, 0, sizeof(hw));
-
-#ifdef CONFIG_PCI_MSI
- hw.msi_ctrl = &pcie->msi.chip;
-#endif
-
- hw.nr_controllers = 1;
- hw.private_data = (void **)&pcie;
- hw.setup = tegra_pcie_setup;
- hw.map_irq = tegra_pcie_map_irq;
- hw.ops = &tegra_pcie_ops;
-
- pci_common_init_dev(dev, &hw);
- return 0;
}
static const struct tegra_pcie_soc tegra20_pcie = {
@@ -2069,6 +2067,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
.has_intr_prsnt_sense = false,
.has_cml_clk = false,
.has_gen2 = false,
+ .force_pca_enable = false,
};
static const struct tegra_pcie_soc tegra30_pcie = {
@@ -2083,6 +2082,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
.has_intr_prsnt_sense = true,
.has_cml_clk = true,
.has_gen2 = false,
+ .force_pca_enable = false,
};
static const struct tegra_pcie_soc tegra124_pcie = {
@@ -2096,9 +2096,25 @@ static const struct tegra_pcie_soc tegra124_pcie = {
.has_intr_prsnt_sense = true,
.has_cml_clk = true,
.has_gen2 = true,
+ .force_pca_enable = false,
+};
+
+static const struct tegra_pcie_soc tegra210_pcie = {
+ .num_ports = 2,
+ .msi_base_shift = 8,
+ .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
+ .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+ .pads_refclk_cfg0 = 0x90b890b8,
+ .has_pex_clkreq_en = true,
+ .has_pex_bias_ctrl = true,
+ .has_intr_prsnt_sense = true,
+ .has_cml_clk = true,
+ .has_gen2 = true,
+ .force_pca_enable = true,
};
static const struct of_device_id tegra_pcie_of_match[] = {
+ { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
{ .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
{ .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },
{ .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },
@@ -2217,13 +2233,17 @@ remove:
static int tegra_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct pci_host_bridge *host;
struct tegra_pcie *pcie;
+ struct pci_bus *child;
int err;
- pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
- if (!pcie)
+ host = pci_alloc_host_bridge(sizeof(*pcie));
+ if (!host)
return -ENOMEM;
+ pcie = pci_host_bridge_priv(host);
+
pcie->soc = of_device_get_match_data(dev);
INIT_LIST_HEAD(&pcie->buses);
INIT_LIST_HEAD(&pcie->ports);
@@ -2243,6 +2263,10 @@ static int tegra_pcie_probe(struct platform_device *pdev)
if (err)
goto put_resources;
+ err = tegra_pcie_request_resources(pcie);
+ if (err)
+ goto put_resources;
+
/* setup the AFI address translations */
tegra_pcie_setup_translations(pcie);
@@ -2254,12 +2278,30 @@ static int tegra_pcie_probe(struct platform_device *pdev)
}
}
- err = tegra_pcie_enable(pcie);
+ tegra_pcie_enable_ports(pcie);
+
+ pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+ host->busnr = pcie->busn.start;
+ host->dev.parent = &pdev->dev;
+ host->ops = &tegra_pcie_ops;
+
+ err = pci_register_host_bridge(host);
if (err < 0) {
- dev_err(dev, "failed to enable PCIe ports: %d\n", err);
+ dev_err(dev, "failed to register host: %d\n", err);
goto disable_msi;
}
+ pci_scan_child_bus(host->bus);
+
+ pci_fixup_irqs(pci_common_swizzle, tegra_pcie_map_irq);
+ pci_bus_size_bridges(host->bus);
+ pci_bus_assign_resources(host->bus);
+
+ list_for_each_entry(child, &host->bus->children, node)
+ pcie_bus_configure_settings(child);
+
+ pci_bus_add_devices(host->bus);
+
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
err = tegra_pcie_debugfs_init(pcie);
if (err < 0)
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c
index d50a3dc2d8db..3f54a43bbbea 100644
--- a/drivers/pci/host/pci-thunder-ecam.c
+++ b/drivers/pci/host/pci-thunder-ecam.c
@@ -14,6 +14,8 @@
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
+#if defined(CONFIG_PCI_HOST_THUNDER_ECAM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
+
static void set_val(u32 v, int where, int size, u32 *val)
{
int shift = (where & 3) * 8;
@@ -346,7 +348,7 @@ static int thunder_ecam_config_write(struct pci_bus *bus, unsigned int devfn,
return pci_generic_config_write(bus, devfn, where, size, val);
}
-static struct pci_ecam_ops pci_thunder_ecam_ops = {
+struct pci_ecam_ops pci_thunder_ecam_ops = {
.bus_shift = 20,
.pci_ops = {
.map_bus = pci_ecam_map_bus,
@@ -355,6 +357,8 @@ static struct pci_ecam_ops pci_thunder_ecam_ops = {
}
};
+#ifdef CONFIG_PCI_HOST_THUNDER_ECAM
+
static const struct of_device_id thunder_ecam_of_match[] = {
{ .compatible = "cavium,pci-host-thunder-ecam" },
{ },
@@ -373,3 +377,6 @@ static struct platform_driver thunder_ecam_driver = {
.probe = thunder_ecam_probe,
};
builtin_platform_driver(thunder_ecam_driver);
+
+#endif
+#endif
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index 6abaf80ffb39..af722eb0ca75 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -18,8 +18,12 @@
#include <linux/init.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
+#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
+#include "../pci.h"
+
+#if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
#define PEM_CFG_WR 0x28
#define PEM_CFG_RD 0x30
@@ -284,35 +288,16 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn,
return pci_generic_config_write(bus, devfn, where, size, val);
}
-static int thunder_pem_init(struct pci_config_window *cfg)
+static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
+ struct resource *res_pem)
{
- struct device *dev = cfg->parent;
- resource_size_t bar4_start;
- struct resource *res_pem;
struct thunder_pem_pci *pem_pci;
- struct platform_device *pdev;
-
- /* Only OF support for now */
- if (!dev->of_node)
- return -EINVAL;
+ resource_size_t bar4_start;
pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL);
if (!pem_pci)
return -ENOMEM;
- pdev = to_platform_device(dev);
-
- /*
- * The second register range is the PEM bridge to the PCIe
- * bus. It has a different config access method than those
- * devices behind the bridge.
- */
- res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res_pem) {
- dev_err(dev, "missing \"reg[1]\"property\n");
- return -EINVAL;
- }
-
pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000);
if (!pem_pci->pem_reg_base)
return -ENOMEM;
@@ -332,9 +317,69 @@ static int thunder_pem_init(struct pci_config_window *cfg)
return 0;
}
+#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
+
+static int thunder_pem_acpi_init(struct pci_config_window *cfg)
+{
+ struct device *dev = cfg->parent;
+ struct acpi_device *adev = to_acpi_device(dev);
+ struct acpi_pci_root *root = acpi_driver_data(adev);
+ struct resource *res_pem;
+ int ret;
+
+ res_pem = devm_kzalloc(&adev->dev, sizeof(*res_pem), GFP_KERNEL);
+ if (!res_pem)
+ return -ENOMEM;
+
+ ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem);
+ if (ret) {
+ dev_err(dev, "can't get rc base address\n");
+ return ret;
+ }
+
+ return thunder_pem_init(dev, cfg, res_pem);
+}
+
+struct pci_ecam_ops thunder_pem_ecam_ops = {
+ .bus_shift = 24,
+ .init = thunder_pem_acpi_init,
+ .pci_ops = {
+ .map_bus = pci_ecam_map_bus,
+ .read = thunder_pem_config_read,
+ .write = thunder_pem_config_write,
+ }
+};
+
+#endif
+
+#ifdef CONFIG_PCI_HOST_THUNDER_PEM
+
+static int thunder_pem_platform_init(struct pci_config_window *cfg)
+{
+ struct device *dev = cfg->parent;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res_pem;
+
+ if (!dev->of_node)
+ return -EINVAL;
+
+ /*
+ * The second register range is the PEM bridge to the PCIe
+ * bus. It has a different config access method than those
+ * devices behind the bridge.
+ */
+ res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res_pem) {
+ dev_err(dev, "missing \"reg[1]\"property\n");
+ return -EINVAL;
+ }
+
+ return thunder_pem_init(dev, cfg, res_pem);
+}
+
static struct pci_ecam_ops pci_thunder_pem_ops = {
.bus_shift = 24,
- .init = thunder_pem_init,
+ .init = thunder_pem_platform_init,
.pci_ops = {
.map_bus = pci_ecam_map_bus,
.read = thunder_pem_config_read,
@@ -360,3 +405,6 @@ static struct platform_driver thunder_pem_driver = {
.probe = thunder_pem_probe,
};
builtin_platform_driver(thunder_pem_driver);
+
+#endif
+#endif
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 1de23d74783f..7c3b54b9eb17 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -27,6 +27,8 @@
#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include <linux/pci.h>
+#include <linux/pci-acpi.h>
+#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -64,7 +66,9 @@
/* PCIe IP version */
#define XGENE_PCIE_IP_VER_UNKN 0
#define XGENE_PCIE_IP_VER_1 1
+#define XGENE_PCIE_IP_VER_2 2
+#if defined(CONFIG_PCI_XGENE) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
struct xgene_pcie_port {
struct device_node *node;
struct device *dev;
@@ -91,13 +95,24 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags)
return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags;
}
+static inline struct xgene_pcie_port *pcie_bus_to_port(struct pci_bus *bus)
+{
+ struct pci_config_window *cfg;
+
+ if (acpi_disabled)
+ return (struct xgene_pcie_port *)(bus->sysdata);
+
+ cfg = bus->sysdata;
+ return (struct xgene_pcie_port *)(cfg->priv);
+}
+
/*
* When the address bit [17:16] is 2'b01, the Configuration access will be
* treated as Type 1 and it will be forwarded to external PCIe device.
*/
static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus)
{
- struct xgene_pcie_port *port = bus->sysdata;
+ struct xgene_pcie_port *port = pcie_bus_to_port(bus);
if (bus->number >= (bus->primary + 1))
return port->cfg_base + AXI_EP_CFG_ACCESS;
@@ -111,7 +126,7 @@ static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus)
*/
static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn)
{
- struct xgene_pcie_port *port = bus->sysdata;
+ struct xgene_pcie_port *port = pcie_bus_to_port(bus);
unsigned int b, d, f;
u32 rtdid_val = 0;
@@ -158,7 +173,7 @@ static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
- struct xgene_pcie_port *port = bus->sysdata;
+ struct xgene_pcie_port *port = pcie_bus_to_port(bus);
if (pci_generic_config_read32(bus, devfn, where & ~0x3, 4, val) !=
PCIBIOS_SUCCESSFUL)
@@ -182,13 +197,103 @@ static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_SUCCESSFUL;
}
+#endif
-static struct pci_ops xgene_pcie_ops = {
- .map_bus = xgene_pcie_map_bus,
- .read = xgene_pcie_config_read32,
- .write = pci_generic_config_write32,
+#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
+static int xgene_get_csr_resource(struct acpi_device *adev,
+ struct resource *res)
+{
+ struct device *dev = &adev->dev;
+ struct resource_entry *entry;
+ struct list_head list;
+ unsigned long flags;
+ int ret;
+
+ INIT_LIST_HEAD(&list);
+ flags = IORESOURCE_MEM;
+ ret = acpi_dev_get_resources(adev, &list,
+ acpi_dev_filter_resource_type_cb,
+ (void *) flags);
+ if (ret < 0) {
+ dev_err(dev, "failed to parse _CRS method, error code %d\n",
+ ret);
+ return ret;
+ }
+
+ if (ret == 0) {
+ dev_err(dev, "no IO and memory resources present in _CRS\n");
+ return -EINVAL;
+ }
+
+ entry = list_first_entry(&list, struct resource_entry, node);
+ *res = *entry->res;
+ acpi_dev_free_resource_list(&list);
+ return 0;
+}
+
+static int xgene_pcie_ecam_init(struct pci_config_window *cfg, u32 ipversion)
+{
+ struct device *dev = cfg->parent;
+ struct acpi_device *adev = to_acpi_device(dev);
+ struct xgene_pcie_port *port;
+ struct resource csr;
+ int ret;
+
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+
+ ret = xgene_get_csr_resource(adev, &csr);
+ if (ret) {
+ dev_err(dev, "can't get CSR resource\n");
+ kfree(port);
+ return ret;
+ }
+ port->csr_base = devm_ioremap_resource(dev, &csr);
+ if (IS_ERR(port->csr_base)) {
+ kfree(port);
+ return -ENOMEM;
+ }
+
+ port->cfg_base = cfg->win;
+ port->version = ipversion;
+
+ cfg->priv = port;
+ return 0;
+}
+
+static int xgene_v1_pcie_ecam_init(struct pci_config_window *cfg)
+{
+ return xgene_pcie_ecam_init(cfg, XGENE_PCIE_IP_VER_1);
+}
+
+struct pci_ecam_ops xgene_v1_pcie_ecam_ops = {
+ .bus_shift = 16,
+ .init = xgene_v1_pcie_ecam_init,
+ .pci_ops = {
+ .map_bus = xgene_pcie_map_bus,
+ .read = xgene_pcie_config_read32,
+ .write = pci_generic_config_write,
+ }
+};
+
+static int xgene_v2_pcie_ecam_init(struct pci_config_window *cfg)
+{
+ return xgene_pcie_ecam_init(cfg, XGENE_PCIE_IP_VER_2);
+}
+
+struct pci_ecam_ops xgene_v2_pcie_ecam_ops = {
+ .bus_shift = 16,
+ .init = xgene_v2_pcie_ecam_init,
+ .pci_ops = {
+ .map_bus = xgene_pcie_map_bus,
+ .read = xgene_pcie_config_read32,
+ .write = pci_generic_config_write,
+ }
};
+#endif
+#if defined(CONFIG_PCI_XGENE)
static u64 xgene_pcie_set_ib_mask(struct xgene_pcie_port *port, u32 addr,
u32 flags, u64 size)
{
@@ -521,6 +626,12 @@ static int xgene_pcie_setup(struct xgene_pcie_port *port,
return 0;
}
+static struct pci_ops xgene_pcie_ops = {
+ .map_bus = xgene_pcie_map_bus,
+ .read = xgene_pcie_config_read32,
+ .write = pci_generic_config_write32,
+};
+
static int xgene_pcie_probe_bridge(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -591,3 +702,4 @@ static struct platform_driver xgene_pcie_driver = {
.probe = xgene_pcie_probe_bridge,
};
builtin_platform_driver(xgene_pcie_driver);
+#endif
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index b0ac4dfafa0b..0c1540225ca3 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -550,10 +550,8 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
pcie->cra_base = devm_ioremap_resource(dev, cra);
- if (IS_ERR(pcie->cra_base)) {
- dev_err(dev, "failed to map cra memory\n");
+ if (IS_ERR(pcie->cra_base))
return PTR_ERR(pcie->cra_base);
- }
/* setup IRQ */
pcie->irq = platform_get_irq(pdev, 0);
@@ -641,8 +639,4 @@ static struct platform_driver altera_pcie_driver = {
},
};
-static int altera_pcie_init(void)
-{
- return platform_driver_register(&altera_pcie_driver);
-}
-device_initcall(altera_pcie_init);
+builtin_platform_driver(altera_pcie_driver);
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c
index 56154c25980c..a301a7187b30 100644
--- a/drivers/pci/host/pcie-hisi.c
+++ b/drivers/pci/host/pcie-hisi.c
@@ -18,7 +18,106 @@
#include <linux/of_pci.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
+#include <linux/pci.h>
+#include <linux/pci-acpi.h>
+#include <linux/pci-ecam.h>
#include <linux/regmap.h>
+#include "../pci.h"
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
+
+static int hisi_pcie_acpi_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ int dev = PCI_SLOT(devfn);
+
+ if (bus->number == cfg->busr.start) {
+ /* access only one slot on each root port */
+ if (dev > 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ else
+ return pci_generic_config_read32(bus, devfn, where,
+ size, val);
+ }
+
+ return pci_generic_config_read(bus, devfn, where, size, val);
+}
+
+static int hisi_pcie_acpi_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ int dev = PCI_SLOT(devfn);
+
+ if (bus->number == cfg->busr.start) {
+ /* access only one slot on each root port */
+ if (dev > 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ else
+ return pci_generic_config_write32(bus, devfn, where,
+ size, val);
+ }
+
+ return pci_generic_config_write(bus, devfn, where, size, val);
+}
+
+static void __iomem *hisi_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *reg_base = cfg->priv;
+
+ if (bus->number == cfg->busr.start)
+ return reg_base + where;
+ else
+ return pci_ecam_map_bus(bus, devfn, where);
+}
+
+static int hisi_pcie_init(struct pci_config_window *cfg)
+{
+ struct device *dev = cfg->parent;
+ struct acpi_device *adev = to_acpi_device(dev);
+ struct acpi_pci_root *root = acpi_driver_data(adev);
+ struct resource *res;
+ void __iomem *reg_base;
+ int ret;
+
+ /*
+ * Retrieve RC base and size from a HISI0081 device with _UID
+ * matching our segment.
+ */
+ res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return -ENOMEM;
+
+ ret = acpi_get_rc_resources(dev, "HISI0081", root->segment, res);
+ if (ret) {
+ dev_err(dev, "can't get rc base address\n");
+ return -ENOMEM;
+ }
+
+ reg_base = devm_ioremap(dev, res->start, resource_size(res));
+ if (!reg_base)
+ return -ENOMEM;
+
+ cfg->priv = reg_base;
+ return 0;
+}
+
+struct pci_ecam_ops hisi_pcie_ops = {
+ .bus_shift = 20,
+ .init = hisi_pcie_init,
+ .pci_ops = {
+ .map_bus = hisi_pcie_map_bus,
+ .read = hisi_pcie_acpi_rd_conf,
+ .write = hisi_pcie_acpi_wr_conf,
+ }
+};
+
+#endif
+
+#ifdef CONFIG_PCI_HISI
#include "pcie-designware.h"
@@ -185,17 +284,13 @@ static int hisi_pcie_probe(struct platform_device *pdev)
reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
pp->dbi_base = devm_ioremap_resource(dev, reg);
- if (IS_ERR(pp->dbi_base)) {
- dev_err(dev, "cannot get rc_dbi base\n");
+ if (IS_ERR(pp->dbi_base))
return PTR_ERR(pp->dbi_base);
- }
ret = hisi_add_pcie_port(hisi_pcie, pdev);
if (ret)
return ret;
- dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n");
-
return 0;
}
@@ -227,3 +322,5 @@ static struct platform_driver hisi_pcie_driver = {
},
};
builtin_platform_driver(hisi_pcie_driver);
+
+#endif
diff --git a/drivers/pci/host/pcie-iproc-bcma.c b/drivers/pci/host/pcie-iproc-bcma.c
index 8ce089043a27..bd4c9ec25edc 100644
--- a/drivers/pci/host/pcie-iproc-bcma.c
+++ b/drivers/pci/host/pcie-iproc-bcma.c
@@ -54,6 +54,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
pcie->dev = dev;
+ pcie->type = IPROC_PCIE_PAXB_BCMA;
pcie->base = bdev->io_addr;
if (!pcie->base) {
dev_err(dev, "no controller registers\n");
diff --git a/drivers/pci/host/pcie-iproc-msi.c b/drivers/pci/host/pcie-iproc-msi.c
index 9a2973bdc78a..9fad7915f82a 100644
--- a/drivers/pci/host/pcie-iproc-msi.c
+++ b/drivers/pci/host/pcie-iproc-msi.c
@@ -563,6 +563,7 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node)
}
switch (pcie->type) {
+ case IPROC_PCIE_PAXB_BCMA:
case IPROC_PCIE_PAXB:
msi->reg_offsets = iproc_msi_reg_paxb;
msi->nr_eq_region = 1;
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
index a3de087976b3..22d814a78a78 100644
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -31,8 +31,14 @@ static const struct of_device_id iproc_pcie_of_match_table[] = {
.compatible = "brcm,iproc-pcie",
.data = (int *)IPROC_PCIE_PAXB,
}, {
+ .compatible = "brcm,iproc-pcie-paxb-v2",
+ .data = (int *)IPROC_PCIE_PAXB_V2,
+ }, {
.compatible = "brcm,iproc-pcie-paxc",
.data = (int *)IPROC_PCIE_PAXC,
+ }, {
+ .compatible = "brcm,iproc-pcie-paxc-v2",
+ .data = (int *)IPROC_PCIE_PAXC_V2,
},
{ /* sentinel */ }
};
@@ -84,19 +90,6 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
return ret;
}
pcie->ob.axi_offset = val;
-
- ret = of_property_read_u32(np, "brcm,pcie-ob-window-size",
- &val);
- if (ret) {
- dev_err(dev,
- "missing brcm,pcie-ob-window-size property\n");
- return ret;
- }
- pcie->ob.window_size = (resource_size_t)val * SZ_1M;
-
- if (of_property_read_bool(np, "brcm,pcie-ob-oarr-size"))
- pcie->ob.set_oarr_size = true;
-
pcie->need_ob_cfg = true;
}
@@ -115,7 +108,14 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
return ret;
}
- pcie->map_irq = of_irq_parse_and_map_pci;
+ /* PAXC doesn't support legacy IRQs, skip mapping */
+ switch (pcie->type) {
+ case IPROC_PCIE_PAXC:
+ case IPROC_PCIE_PAXC_V2:
+ break;
+ default:
+ pcie->map_irq = of_irq_parse_and_map_pci;
+ }
ret = iproc_pcie_setup(pcie, &res);
if (ret)
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index 0b999a9fb843..3ebc025499b9 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/irqchip/arm-gic-v3.h>
#include <linux/platform_device.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
@@ -38,6 +39,12 @@
#define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT)
#define PAXC_RESET_MASK 0x7f
+#define GIC_V3_CFG_SHIFT 0
+#define GIC_V3_CFG BIT(GIC_V3_CFG_SHIFT)
+
+#define MSI_ENABLE_CFG_SHIFT 0
+#define MSI_ENABLE_CFG BIT(MSI_ENABLE_CFG_SHIFT)
+
#define CFG_IND_ADDR_MASK 0x00001ffc
#define CFG_ADDR_BUS_NUM_SHIFT 20
@@ -58,59 +65,319 @@
#define PCIE_DL_ACTIVE_SHIFT 2
#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
+#define APB_ERR_EN_SHIFT 0
+#define APB_ERR_EN BIT(APB_ERR_EN_SHIFT)
+
+/* derive the enum index of the outbound/inbound mapping registers */
+#define MAP_REG(base_reg, index) ((base_reg) + (index) * 2)
+
+/*
+ * Maximum number of outbound mapping window sizes that can be supported by any
+ * OARR/OMAP mapping pair
+ */
+#define MAX_NUM_OB_WINDOW_SIZES 4
+
#define OARR_VALID_SHIFT 0
#define OARR_VALID BIT(OARR_VALID_SHIFT)
#define OARR_SIZE_CFG_SHIFT 1
-#define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT)
-#define PCI_EXP_CAP 0xac
+/*
+ * Maximum number of inbound mapping region sizes that can be supported by an
+ * IARR
+ */
+#define MAX_NUM_IB_REGION_SIZES 9
+
+#define IMAP_VALID_SHIFT 0
+#define IMAP_VALID BIT(IMAP_VALID_SHIFT)
-#define MAX_NUM_OB_WINDOWS 2
+#define PCI_EXP_CAP 0xac
#define IPROC_PCIE_REG_INVALID 0xffff
+/**
+ * iProc PCIe outbound mapping controller specific parameters
+ *
+ * @window_sizes: list of supported outbound mapping window sizes in MB
+ * @nr_sizes: number of supported outbound mapping window sizes
+ */
+struct iproc_pcie_ob_map {
+ resource_size_t window_sizes[MAX_NUM_OB_WINDOW_SIZES];
+ unsigned int nr_sizes;
+};
+
+static const struct iproc_pcie_ob_map paxb_ob_map[] = {
+ {
+ /* OARR0/OMAP0 */
+ .window_sizes = { 128, 256 },
+ .nr_sizes = 2,
+ },
+ {
+ /* OARR1/OMAP1 */
+ .window_sizes = { 128, 256 },
+ .nr_sizes = 2,
+ },
+};
+
+static const struct iproc_pcie_ob_map paxb_v2_ob_map[] = {
+ {
+ /* OARR0/OMAP0 */
+ .window_sizes = { 128, 256 },
+ .nr_sizes = 2,
+ },
+ {
+ /* OARR1/OMAP1 */
+ .window_sizes = { 128, 256 },
+ .nr_sizes = 2,
+ },
+ {
+ /* OARR2/OMAP2 */
+ .window_sizes = { 128, 256, 512, 1024 },
+ .nr_sizes = 4,
+ },
+ {
+ /* OARR3/OMAP3 */
+ .window_sizes = { 128, 256, 512, 1024 },
+ .nr_sizes = 4,
+ },
+};
+
+/**
+ * iProc PCIe inbound mapping type
+ */
+enum iproc_pcie_ib_map_type {
+ /* for DDR memory */
+ IPROC_PCIE_IB_MAP_MEM = 0,
+
+ /* for device I/O memory */
+ IPROC_PCIE_IB_MAP_IO,
+
+ /* invalid or unused */
+ IPROC_PCIE_IB_MAP_INVALID
+};
+
+/**
+ * iProc PCIe inbound mapping controller specific parameters
+ *
+ * @type: inbound mapping region type
+ * @size_unit: inbound mapping region size unit, could be SZ_1K, SZ_1M, or
+ * SZ_1G
+ * @region_sizes: list of supported inbound mapping region sizes in KB, MB, or
+ * GB, depedning on the size unit
+ * @nr_sizes: number of supported inbound mapping region sizes
+ * @nr_windows: number of supported inbound mapping windows for the region
+ * @imap_addr_offset: register offset between the upper and lower 32-bit
+ * IMAP address registers
+ * @imap_window_offset: register offset between each IMAP window
+ */
+struct iproc_pcie_ib_map {
+ enum iproc_pcie_ib_map_type type;
+ unsigned int size_unit;
+ resource_size_t region_sizes[MAX_NUM_IB_REGION_SIZES];
+ unsigned int nr_sizes;
+ unsigned int nr_windows;
+ u16 imap_addr_offset;
+ u16 imap_window_offset;
+};
+
+static const struct iproc_pcie_ib_map paxb_v2_ib_map[] = {
+ {
+ /* IARR0/IMAP0 */
+ .type = IPROC_PCIE_IB_MAP_IO,
+ .size_unit = SZ_1K,
+ .region_sizes = { 32 },
+ .nr_sizes = 1,
+ .nr_windows = 8,
+ .imap_addr_offset = 0x40,
+ .imap_window_offset = 0x4,
+ },
+ {
+ /* IARR1/IMAP1 (currently unused) */
+ .type = IPROC_PCIE_IB_MAP_INVALID,
+ },
+ {
+ /* IARR2/IMAP2 */
+ .type = IPROC_PCIE_IB_MAP_MEM,
+ .size_unit = SZ_1M,
+ .region_sizes = { 64, 128, 256, 512, 1024, 2048, 4096, 8192,
+ 16384 },
+ .nr_sizes = 9,
+ .nr_windows = 1,
+ .imap_addr_offset = 0x4,
+ .imap_window_offset = 0x8,
+ },
+ {
+ /* IARR3/IMAP3 */
+ .type = IPROC_PCIE_IB_MAP_MEM,
+ .size_unit = SZ_1G,
+ .region_sizes = { 1, 2, 4, 8, 16, 32 },
+ .nr_sizes = 6,
+ .nr_windows = 8,
+ .imap_addr_offset = 0x4,
+ .imap_window_offset = 0x8,
+ },
+ {
+ /* IARR4/IMAP4 */
+ .type = IPROC_PCIE_IB_MAP_MEM,
+ .size_unit = SZ_1G,
+ .region_sizes = { 32, 64, 128, 256, 512 },
+ .nr_sizes = 5,
+ .nr_windows = 8,
+ .imap_addr_offset = 0x4,
+ .imap_window_offset = 0x8,
+ },
+};
+
+/*
+ * iProc PCIe host registers
+ */
enum iproc_pcie_reg {
+ /* clock/reset signal control */
IPROC_PCIE_CLK_CTRL = 0,
+
+ /*
+ * To allow MSI to be steered to an external MSI controller (e.g., ARM
+ * GICv3 ITS)
+ */
+ IPROC_PCIE_MSI_GIC_MODE,
+
+ /*
+ * IPROC_PCIE_MSI_BASE_ADDR and IPROC_PCIE_MSI_WINDOW_SIZE define the
+ * window where the MSI posted writes are written, for the writes to be
+ * interpreted as MSI writes.
+ */
+ IPROC_PCIE_MSI_BASE_ADDR,
+ IPROC_PCIE_MSI_WINDOW_SIZE,
+
+ /*
+ * To hold the address of the register where the MSI writes are
+ * programed. When ARM GICv3 ITS is used, this should be programmed
+ * with the address of the GITS_TRANSLATER register.
+ */
+ IPROC_PCIE_MSI_ADDR_LO,
+ IPROC_PCIE_MSI_ADDR_HI,
+
+ /* enable MSI */
+ IPROC_PCIE_MSI_EN_CFG,
+
+ /* allow access to root complex configuration space */
IPROC_PCIE_CFG_IND_ADDR,
IPROC_PCIE_CFG_IND_DATA,
+
+ /* allow access to device configuration space */
IPROC_PCIE_CFG_ADDR,
IPROC_PCIE_CFG_DATA,
+
+ /* enable INTx */
IPROC_PCIE_INTX_EN,
- IPROC_PCIE_OARR_LO,
- IPROC_PCIE_OARR_HI,
- IPROC_PCIE_OMAP_LO,
- IPROC_PCIE_OMAP_HI,
+
+ /* outbound address mapping */
+ IPROC_PCIE_OARR0,
+ IPROC_PCIE_OMAP0,
+ IPROC_PCIE_OARR1,
+ IPROC_PCIE_OMAP1,
+ IPROC_PCIE_OARR2,
+ IPROC_PCIE_OMAP2,
+ IPROC_PCIE_OARR3,
+ IPROC_PCIE_OMAP3,
+
+ /* inbound address mapping */
+ IPROC_PCIE_IARR0,
+ IPROC_PCIE_IMAP0,
+ IPROC_PCIE_IARR1,
+ IPROC_PCIE_IMAP1,
+ IPROC_PCIE_IARR2,
+ IPROC_PCIE_IMAP2,
+ IPROC_PCIE_IARR3,
+ IPROC_PCIE_IMAP3,
+ IPROC_PCIE_IARR4,
+ IPROC_PCIE_IMAP4,
+
+ /* link status */
IPROC_PCIE_LINK_STATUS,
+
+ /* enable APB error for unsupported requests */
+ IPROC_PCIE_APB_ERR_EN,
+
+ /* total number of core registers */
+ IPROC_PCIE_MAX_NUM_REG,
+};
+
+/* iProc PCIe PAXB BCMA registers */
+static const u16 iproc_pcie_reg_paxb_bcma[] = {
+ [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_LINK_STATUS] = 0xf0c,
};
/* 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_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_OARR0] = 0xd20,
+ [IPROC_PCIE_OMAP0] = 0xd40,
+ [IPROC_PCIE_OARR1] = 0xd28,
+ [IPROC_PCIE_OMAP1] = 0xd48,
+ [IPROC_PCIE_LINK_STATUS] = 0xf0c,
+ [IPROC_PCIE_APB_ERR_EN] = 0xf40,
+};
+
+/* iProc PCIe PAXB v2 registers */
+static const u16 iproc_pcie_reg_paxb_v2[] = {
+ [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_OARR0] = 0xd20,
+ [IPROC_PCIE_OMAP0] = 0xd40,
+ [IPROC_PCIE_OARR1] = 0xd28,
+ [IPROC_PCIE_OMAP1] = 0xd48,
+ [IPROC_PCIE_OARR2] = 0xd60,
+ [IPROC_PCIE_OMAP2] = 0xd68,
+ [IPROC_PCIE_OARR3] = 0xdf0,
+ [IPROC_PCIE_OMAP3] = 0xdf8,
+ [IPROC_PCIE_IARR0] = 0xd00,
+ [IPROC_PCIE_IMAP0] = 0xc00,
+ [IPROC_PCIE_IARR2] = 0xd10,
+ [IPROC_PCIE_IMAP2] = 0xcc0,
+ [IPROC_PCIE_IARR3] = 0xe00,
+ [IPROC_PCIE_IMAP3] = 0xe08,
+ [IPROC_PCIE_IARR4] = 0xe68,
+ [IPROC_PCIE_IMAP4] = 0xe70,
+ [IPROC_PCIE_LINK_STATUS] = 0xf0c,
+ [IPROC_PCIE_APB_ERR_EN] = 0xf40,
};
/* 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,
+ [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 PAXC v2 registers */
+static const u16 iproc_pcie_reg_paxc_v2[] = {
+ [IPROC_PCIE_MSI_GIC_MODE] = 0x050,
+ [IPROC_PCIE_MSI_BASE_ADDR] = 0x074,
+ [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078,
+ [IPROC_PCIE_MSI_ADDR_LO] = 0x07c,
+ [IPROC_PCIE_MSI_ADDR_HI] = 0x080,
+ [IPROC_PCIE_MSI_EN_CFG] = 0x09c,
+ [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
+ [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
+ [IPROC_PCIE_CFG_ADDR] = 0x1f8,
+ [IPROC_PCIE_CFG_DATA] = 0x1fc,
};
static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
@@ -159,16 +426,26 @@ static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie,
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)
+/**
+ * APB error forwarding can be disabled during access of configuration
+ * registers of the endpoint device, to prevent unsupported requests
+ * (typically seen during enumeration with multi-function devices) from
+ * triggering a system exception.
+ */
+static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,
+ bool disable)
{
- u16 offset = iproc_pcie_reg_offset(pcie, reg);
-
- if (iproc_pcie_reg_is_invalid(offset))
- return;
+ struct iproc_pcie *pcie = iproc_data(bus);
+ u32 val;
- writel(val, pcie->base + offset + (window * 8));
+ if (bus->number && pcie->has_apb_err_disable) {
+ val = iproc_pcie_read_reg(pcie, IPROC_PCIE_APB_ERR_EN);
+ if (disable)
+ val &= ~APB_ERR_EN;
+ else
+ val |= APB_ERR_EN;
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_APB_ERR_EN, val);
+ }
}
/**
@@ -204,7 +481,7 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
* PAXC is connected to an internally emulated EP within the SoC. It
* allows only one device.
*/
- if (pcie->type == IPROC_PCIE_PAXC)
+ if (pcie->ep_is_internal)
if (slot > 0)
return NULL;
@@ -222,26 +499,47 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
return (pcie->base + offset);
}
+static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ int ret;
+
+ iproc_pcie_apb_err_disable(bus, true);
+ ret = pci_generic_config_read32(bus, devfn, where, size, val);
+ iproc_pcie_apb_err_disable(bus, false);
+
+ return ret;
+}
+
+static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ int ret;
+
+ iproc_pcie_apb_err_disable(bus, true);
+ ret = pci_generic_config_write32(bus, devfn, where, size, val);
+ iproc_pcie_apb_err_disable(bus, false);
+
+ return ret;
+}
+
static struct pci_ops iproc_pcie_ops = {
.map_bus = iproc_pcie_map_cfg_bus,
- .read = pci_generic_config_read32,
- .write = pci_generic_config_write32,
+ .read = iproc_pcie_config_read32,
+ .write = iproc_pcie_config_write32,
};
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);
+ /*
+ * PAXC and the internal emulated endpoint device downstream should not
+ * be reset. If firmware has been loaded on the endpoint device at an
+ * earlier boot stage, reset here causes issues.
+ */
+ if (pcie->ep_is_internal)
return;
- }
/*
* Select perst_b signal as reset source. Put the device into reset,
@@ -270,7 +568,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
* 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)
+ if (pcie->ep_is_internal)
return 0;
val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
@@ -334,6 +632,58 @@ static void iproc_pcie_enable(struct iproc_pcie *pcie)
iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK);
}
+static inline bool iproc_pcie_ob_is_valid(struct iproc_pcie *pcie,
+ int window_idx)
+{
+ u32 val;
+
+ val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_OARR0, window_idx));
+
+ return !!(val & OARR_VALID);
+}
+
+static inline int iproc_pcie_ob_write(struct iproc_pcie *pcie, int window_idx,
+ int size_idx, u64 axi_addr, u64 pci_addr)
+{
+ struct device *dev = pcie->dev;
+ u16 oarr_offset, omap_offset;
+
+ /*
+ * Derive the OARR/OMAP offset from the first pair (OARR0/OMAP0) based
+ * on window index.
+ */
+ oarr_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OARR0,
+ window_idx));
+ omap_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OMAP0,
+ window_idx));
+ if (iproc_pcie_reg_is_invalid(oarr_offset) ||
+ iproc_pcie_reg_is_invalid(omap_offset))
+ return -EINVAL;
+
+ /*
+ * Program the OARR registers. The upper 32-bit OARR register is
+ * always right after the lower 32-bit OARR register.
+ */
+ writel(lower_32_bits(axi_addr) | (size_idx << OARR_SIZE_CFG_SHIFT) |
+ OARR_VALID, pcie->base + oarr_offset);
+ writel(upper_32_bits(axi_addr), pcie->base + oarr_offset + 4);
+
+ /* now program the OMAP registers */
+ writel(lower_32_bits(pci_addr), pcie->base + omap_offset);
+ writel(upper_32_bits(pci_addr), pcie->base + omap_offset + 4);
+
+ dev_info(dev, "ob window [%d]: offset 0x%x axi %pap pci %pap\n",
+ window_idx, oarr_offset, &axi_addr, &pci_addr);
+ dev_info(dev, "oarr lo 0x%x oarr hi 0x%x\n",
+ readl(pcie->base + oarr_offset),
+ readl(pcie->base + oarr_offset + 4));
+ dev_info(dev, "omap lo 0x%x omap hi 0x%x\n",
+ readl(pcie->base + omap_offset),
+ readl(pcie->base + omap_offset + 4));
+
+ return 0;
+}
+
/**
* Some iProc SoCs require the SW to configure the outbound address mapping
*
@@ -350,24 +700,7 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
{
struct iproc_pcie_ob *ob = &pcie->ob;
struct device *dev = pcie->dev;
- unsigned i;
- u64 max_size = (u64)ob->window_size * MAX_NUM_OB_WINDOWS;
- u64 remainder;
-
- if (size > max_size) {
- dev_err(dev,
- "res size %pap exceeds max supported size 0x%llx\n",
- &size, max_size);
- return -EINVAL;
- }
-
- div64_u64_rem(size, ob->window_size, &remainder);
- if (remainder) {
- dev_err(dev,
- "res size %pap needs to be multiple of window size %pap\n",
- &size, &ob->window_size);
- return -EINVAL;
- }
+ int ret = -EINVAL, window_idx, size_idx;
if (axi_addr < ob->axi_offset) {
dev_err(dev, "axi address %pap less than offset %pap\n",
@@ -381,26 +714,70 @@ 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++) {
- 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)
+ /* iterate through all OARR/OMAP mapping windows */
+ for (window_idx = ob->nr_windows - 1; window_idx >= 0; window_idx--) {
+ const struct iproc_pcie_ob_map *ob_map =
+ &pcie->ob_map[window_idx];
+
+ /*
+ * If current outbound window is already in use, move on to the
+ * next one.
+ */
+ if (iproc_pcie_ob_is_valid(pcie, window_idx))
+ continue;
+
+ /*
+ * Iterate through all supported window sizes within the
+ * OARR/OMAP pair to find a match. Go through the window sizes
+ * in a descending order.
+ */
+ for (size_idx = ob_map->nr_sizes - 1; size_idx >= 0;
+ size_idx--) {
+ resource_size_t window_size =
+ ob_map->window_sizes[size_idx] * SZ_1M;
+
+ if (size < window_size)
+ continue;
+
+ if (!IS_ALIGNED(axi_addr, window_size) ||
+ !IS_ALIGNED(pci_addr, window_size)) {
+ dev_err(dev,
+ "axi %pap or pci %pap not aligned\n",
+ &axi_addr, &pci_addr);
+ return -EINVAL;
+ }
+
+ /*
+ * Match found! Program both OARR and OMAP and mark
+ * them as a valid entry.
+ */
+ ret = iproc_pcie_ob_write(pcie, window_idx, size_idx,
+ axi_addr, pci_addr);
+ if (ret)
+ goto err_ob;
+
+ size -= window_size;
+ if (size == 0)
+ return 0;
+
+ /*
+ * If we are here, we are done with the current window,
+ * but not yet finished all mappings. Need to move on
+ * to the next window.
+ */
+ axi_addr += window_size;
+ pci_addr += window_size;
break;
-
- axi_addr += ob->window_size;
- pci_addr += ob->window_size;
+ }
}
- return 0;
+err_ob:
+ dev_err(dev, "unable to configure outbound mapping\n");
+ dev_err(dev,
+ "axi %pap, axi offset %pap, pci %pap, res size %pap\n",
+ &axi_addr, &ob->axi_offset, &pci_addr, &size);
+
+ return ret;
}
static int iproc_pcie_map_ranges(struct iproc_pcie *pcie,
@@ -434,13 +811,323 @@ static int iproc_pcie_map_ranges(struct iproc_pcie *pcie,
return 0;
}
+static inline bool iproc_pcie_ib_is_in_use(struct iproc_pcie *pcie,
+ int region_idx)
+{
+ const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx];
+ u32 val;
+
+ val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_IARR0, region_idx));
+
+ return !!(val & (BIT(ib_map->nr_sizes) - 1));
+}
+
+static inline bool iproc_pcie_ib_check_type(const struct iproc_pcie_ib_map *ib_map,
+ enum iproc_pcie_ib_map_type type)
+{
+ return !!(ib_map->type == type);
+}
+
+static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx,
+ int size_idx, int nr_windows, u64 axi_addr,
+ u64 pci_addr, resource_size_t size)
+{
+ struct device *dev = pcie->dev;
+ const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx];
+ u16 iarr_offset, imap_offset;
+ u32 val;
+ int window_idx;
+
+ iarr_offset = iproc_pcie_reg_offset(pcie,
+ MAP_REG(IPROC_PCIE_IARR0, region_idx));
+ imap_offset = iproc_pcie_reg_offset(pcie,
+ MAP_REG(IPROC_PCIE_IMAP0, region_idx));
+ if (iproc_pcie_reg_is_invalid(iarr_offset) ||
+ iproc_pcie_reg_is_invalid(imap_offset))
+ return -EINVAL;
+
+ dev_info(dev, "ib region [%d]: offset 0x%x axi %pap pci %pap\n",
+ region_idx, iarr_offset, &axi_addr, &pci_addr);
+
+ /*
+ * Program the IARR registers. The upper 32-bit IARR register is
+ * always right after the lower 32-bit IARR register.
+ */
+ writel(lower_32_bits(pci_addr) | BIT(size_idx),
+ pcie->base + iarr_offset);
+ writel(upper_32_bits(pci_addr), pcie->base + iarr_offset + 4);
+
+ dev_info(dev, "iarr lo 0x%x iarr hi 0x%x\n",
+ readl(pcie->base + iarr_offset),
+ readl(pcie->base + iarr_offset + 4));
+
+ /*
+ * Now program the IMAP registers. Each IARR region may have one or
+ * more IMAP windows.
+ */
+ size >>= ilog2(nr_windows);
+ for (window_idx = 0; window_idx < nr_windows; window_idx++) {
+ val = readl(pcie->base + imap_offset);
+ val |= lower_32_bits(axi_addr) | IMAP_VALID;
+ writel(val, pcie->base + imap_offset);
+ writel(upper_32_bits(axi_addr),
+ pcie->base + imap_offset + ib_map->imap_addr_offset);
+
+ dev_info(dev, "imap window [%d] lo 0x%x hi 0x%x\n",
+ window_idx, readl(pcie->base + imap_offset),
+ readl(pcie->base + imap_offset +
+ ib_map->imap_addr_offset));
+
+ imap_offset += ib_map->imap_window_offset;
+ axi_addr += size;
+ }
+
+ return 0;
+}
+
+static int iproc_pcie_setup_ib(struct iproc_pcie *pcie,
+ struct of_pci_range *range,
+ enum iproc_pcie_ib_map_type type)
+{
+ struct device *dev = pcie->dev;
+ struct iproc_pcie_ib *ib = &pcie->ib;
+ int ret;
+ unsigned int region_idx, size_idx;
+ u64 axi_addr = range->cpu_addr, pci_addr = range->pci_addr;
+ resource_size_t size = range->size;
+
+ /* iterate through all IARR mapping regions */
+ for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) {
+ const struct iproc_pcie_ib_map *ib_map =
+ &pcie->ib_map[region_idx];
+
+ /*
+ * If current inbound region is already in use or not a
+ * compatible type, move on to the next.
+ */
+ if (iproc_pcie_ib_is_in_use(pcie, region_idx) ||
+ !iproc_pcie_ib_check_type(ib_map, type))
+ continue;
+
+ /* iterate through all supported region sizes to find a match */
+ for (size_idx = 0; size_idx < ib_map->nr_sizes; size_idx++) {
+ resource_size_t region_size =
+ ib_map->region_sizes[size_idx] * ib_map->size_unit;
+
+ if (size != region_size)
+ continue;
+
+ if (!IS_ALIGNED(axi_addr, region_size) ||
+ !IS_ALIGNED(pci_addr, region_size)) {
+ dev_err(dev,
+ "axi %pap or pci %pap not aligned\n",
+ &axi_addr, &pci_addr);
+ return -EINVAL;
+ }
+
+ /* Match found! Program IARR and all IMAP windows. */
+ ret = iproc_pcie_ib_write(pcie, region_idx, size_idx,
+ ib_map->nr_windows, axi_addr,
+ pci_addr, size);
+ if (ret)
+ goto err_ib;
+ else
+ return 0;
+
+ }
+ }
+ ret = -EINVAL;
+
+err_ib:
+ dev_err(dev, "unable to configure inbound mapping\n");
+ dev_err(dev, "axi %pap, pci %pap, res size %pap\n",
+ &axi_addr, &pci_addr, &size);
+
+ return ret;
+}
+
+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 iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)
+{
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ int ret;
+
+ /* Get the dma-ranges from DT */
+ ret = pci_dma_range_parser_init(&parser, pcie->dev->of_node);
+ if (ret)
+ return ret;
+
+ for_each_of_pci_range(&parser, &range) {
+ /* Each range entry corresponds to an inbound mapping region */
+ ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_MEM);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int iproce_pcie_get_msi(struct iproc_pcie *pcie,
+ struct device_node *msi_node,
+ u64 *msi_addr)
+{
+ struct device *dev = pcie->dev;
+ int ret;
+ struct resource res;
+
+ /*
+ * Check if 'msi-map' points to ARM GICv3 ITS, which is the only
+ * supported external MSI controller that requires steering.
+ */
+ if (!of_device_is_compatible(msi_node, "arm,gic-v3-its")) {
+ dev_err(dev, "unable to find compatible MSI controller\n");
+ return -ENODEV;
+ }
+
+ /* derive GITS_TRANSLATER address from GICv3 */
+ ret = of_address_to_resource(msi_node, 0, &res);
+ if (ret < 0) {
+ dev_err(dev, "unable to obtain MSI controller resources\n");
+ return ret;
+ }
+
+ *msi_addr = res.start + GITS_TRANSLATER;
+ return 0;
+}
+
+static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
+{
+ int ret;
+ struct of_pci_range range;
+
+ memset(&range, 0, sizeof(range));
+ range.size = SZ_32K;
+ range.pci_addr = range.cpu_addr = msi_addr & ~(range.size - 1);
+
+ ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_IO);
+ return ret;
+}
+
+static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
+{
+ u32 val;
+
+ /*
+ * Program bits [43:13] of address of GITS_TRANSLATER register into
+ * bits [30:0] of the MSI base address register. In fact, in all iProc
+ * based SoCs, all I/O register bases are well below the 32-bit
+ * boundary, so we can safely assume bits [43:32] are always zeros.
+ */
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_BASE_ADDR,
+ (u32)(msi_addr >> 13));
+
+ /* use a default 8K window size */
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_WINDOW_SIZE, 0);
+
+ /* steering MSI to GICv3 ITS */
+ val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_GIC_MODE);
+ val |= GIC_V3_CFG;
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_GIC_MODE, val);
+
+ /*
+ * Program bits [43:2] of address of GITS_TRANSLATER register into the
+ * iProc MSI address registers.
+ */
+ msi_addr >>= 2;
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_HI,
+ upper_32_bits(msi_addr));
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_LO,
+ lower_32_bits(msi_addr));
+
+ /* enable MSI */
+ val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG);
+ val |= MSI_ENABLE_CFG;
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val);
+}
+
+static int iproc_pcie_msi_steer(struct iproc_pcie *pcie,
+ struct device_node *msi_node)
+{
+ struct device *dev = pcie->dev;
+ int ret;
+ u64 msi_addr;
+
+ ret = iproce_pcie_get_msi(pcie, msi_node, &msi_addr);
+ if (ret < 0) {
+ dev_err(dev, "msi steering failed\n");
+ return ret;
+ }
+
+ switch (pcie->type) {
+ case IPROC_PCIE_PAXB_V2:
+ ret = iproc_pcie_paxb_v2_msi_steer(pcie, msi_addr);
+ if (ret)
+ return ret;
+ break;
+ case IPROC_PCIE_PAXC_V2:
+ iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int iproc_pcie_msi_enable(struct iproc_pcie *pcie)
{
struct device_node *msi_node;
+ int ret;
+
+ /*
+ * Either the "msi-parent" or the "msi-map" phandle needs to exist
+ * for us to obtain the MSI node.
+ */
msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0);
- if (!msi_node)
- return -ENODEV;
+ if (!msi_node) {
+ const __be32 *msi_map = NULL;
+ int len;
+ u32 phandle;
+
+ msi_map = of_get_property(pcie->dev->of_node, "msi-map", &len);
+ if (!msi_map)
+ return -ENODEV;
+
+ phandle = be32_to_cpup(msi_map + 1);
+ msi_node = of_find_node_by_phandle(phandle);
+ if (!msi_node)
+ return -ENODEV;
+ }
+
+ /*
+ * Certain revisions of the iProc PCIe controller require additional
+ * configurations to steer the MSI writes towards an external MSI
+ * controller.
+ */
+ if (pcie->need_msi_steer) {
+ ret = iproc_pcie_msi_steer(pcie, msi_node);
+ if (ret)
+ return ret;
+ }
/*
* If another MSI controller is being used, the call below should fail
@@ -454,6 +1141,65 @@ static void iproc_pcie_msi_disable(struct iproc_pcie *pcie)
iproc_msi_exit(pcie);
}
+static int iproc_pcie_rev_init(struct iproc_pcie *pcie)
+{
+ struct device *dev = pcie->dev;
+ unsigned int reg_idx;
+ const u16 *regs;
+
+ switch (pcie->type) {
+ case IPROC_PCIE_PAXB_BCMA:
+ regs = iproc_pcie_reg_paxb_bcma;
+ break;
+ case IPROC_PCIE_PAXB:
+ regs = iproc_pcie_reg_paxb;
+ pcie->has_apb_err_disable = true;
+ if (pcie->need_ob_cfg) {
+ pcie->ob_map = paxb_ob_map;
+ pcie->ob.nr_windows = ARRAY_SIZE(paxb_ob_map);
+ }
+ break;
+ case IPROC_PCIE_PAXB_V2:
+ regs = iproc_pcie_reg_paxb_v2;
+ pcie->has_apb_err_disable = true;
+ if (pcie->need_ob_cfg) {
+ pcie->ob_map = paxb_v2_ob_map;
+ pcie->ob.nr_windows = ARRAY_SIZE(paxb_v2_ob_map);
+ }
+ pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map);
+ pcie->ib_map = paxb_v2_ib_map;
+ pcie->need_msi_steer = true;
+ break;
+ case IPROC_PCIE_PAXC:
+ regs = iproc_pcie_reg_paxc;
+ pcie->ep_is_internal = true;
+ break;
+ case IPROC_PCIE_PAXC_V2:
+ regs = iproc_pcie_reg_paxc_v2;
+ pcie->ep_is_internal = true;
+ pcie->need_msi_steer = true;
+ break;
+ default:
+ dev_err(dev, "incompatible iProc PCIe interface\n");
+ return -EINVAL;
+ }
+
+ pcie->reg_offsets = devm_kcalloc(dev, IPROC_PCIE_MAX_NUM_REG,
+ sizeof(*pcie->reg_offsets),
+ GFP_KERNEL);
+ if (!pcie->reg_offsets)
+ return -ENOMEM;
+
+ /* go through the register table and populate all valid registers */
+ pcie->reg_offsets[0] = (pcie->type == IPROC_PCIE_PAXC_V2) ?
+ IPROC_PCIE_REG_INVALID : regs[0];
+ for (reg_idx = 1; reg_idx < IPROC_PCIE_MAX_NUM_REG; reg_idx++)
+ pcie->reg_offsets[reg_idx] = regs[reg_idx] ?
+ regs[reg_idx] : IPROC_PCIE_REG_INVALID;
+
+ return 0;
+}
+
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
{
struct device *dev;
@@ -462,6 +1208,13 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
struct pci_bus *bus;
dev = pcie->dev;
+
+ ret = iproc_pcie_rev_init(pcie);
+ if (ret) {
+ dev_err(dev, "unable to initialize controller parameters\n");
+ return ret;
+ }
+
ret = devm_request_pci_bus_resources(dev, res);
if (ret)
return ret;
@@ -478,19 +1231,6 @@ 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(dev, "incompatible iProc PCIe interface\n");
- ret = -EINVAL;
- goto err_power_off_phy;
- }
-
iproc_pcie_reset(pcie);
if (pcie->need_ob_cfg) {
@@ -501,6 +1241,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
}
}
+ ret = iproc_pcie_map_dma_ranges(pcie);
+ if (ret && ret != -ENOENT)
+ goto err_power_off_phy;
+
#ifdef CONFIG_ARM
pcie->sysdata.private_data = pcie;
sysdata = &pcie->sysdata;
@@ -530,7 +1274,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
pci_scan_child_bus(bus);
pci_assign_unassigned_bus_resources(bus);
- pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
+
+ if (pcie->map_irq)
+ pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
+
pci_bus_add_devices(bus);
return 0;
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h
index e84d93c53c7b..04fed8e907f1 100644
--- a/drivers/pci/host/pcie-iproc.h
+++ b/drivers/pci/host/pcie-iproc.h
@@ -24,23 +24,34 @@
* endpoint devices.
*/
enum iproc_pcie_type {
- IPROC_PCIE_PAXB = 0,
+ IPROC_PCIE_PAXB_BCMA = 0,
+ IPROC_PCIE_PAXB,
+ IPROC_PCIE_PAXB_V2,
IPROC_PCIE_PAXC,
+ IPROC_PCIE_PAXC_V2,
};
/**
* iProc PCIe outbound mapping
- * @set_oarr_size: indicates the OARR size bit needs to be set
* @axi_offset: offset from the AXI address to the internal address used by
* the iProc PCIe core
- * @window_size: outbound window size
+ * @nr_windows: total number of supported outbound mapping windows
*/
struct iproc_pcie_ob {
- bool set_oarr_size;
resource_size_t axi_offset;
- resource_size_t window_size;
+ unsigned int nr_windows;
};
+/**
+ * iProc PCIe inbound mapping
+ * @nr_regions: total number of supported inbound mapping regions
+ */
+struct iproc_pcie_ib {
+ unsigned int nr_regions;
+};
+
+struct iproc_pcie_ob_map;
+struct iproc_pcie_ib_map;
struct iproc_msi;
/**
@@ -55,14 +66,25 @@ struct iproc_msi;
* @root_bus: pointer to root bus
* @phy: optional PHY device that controls the Serdes
* @map_irq: function callback to map interrupts
+ * @ep_is_internal: indicates an internal emulated endpoint device is connected
+ * @has_apb_err_disable: indicates the controller can be configured to prevent
+ * unsupported request from being forwarded as an APB bus error
+ *
* @need_ob_cfg: indicates SW needs to configure the outbound mapping window
- * @ob: outbound mapping parameters
+ * @ob: outbound mapping related parameters
+ * @ob_map: outbound mapping related parameters specific to the controller
+ *
+ * @ib: inbound mapping related parameters
+ * @ib_map: outbound mapping region related parameters
+ *
+ * @need_msi_steer: indicates additional configuration of the iProc PCIe
+ * controller is required to steer MSI writes to external interrupt controller
* @msi: MSI data
*/
struct iproc_pcie {
struct device *dev;
enum iproc_pcie_type type;
- const u16 *reg_offsets;
+ u16 *reg_offsets;
void __iomem *base;
phys_addr_t base_addr;
#ifdef CONFIG_ARM
@@ -71,8 +93,17 @@ struct iproc_pcie {
struct pci_bus *root_bus;
struct phy *phy;
int (*map_irq)(const struct pci_dev *, u8, u8);
+ bool ep_is_internal;
+ bool has_apb_err_disable;
+
bool need_ob_cfg;
struct iproc_pcie_ob ob;
+ const struct iproc_pcie_ob_map *ob_map;
+
+ struct iproc_pcie_ib ib;
+ const struct iproc_pcie_ib_map *ib_map;
+
+ bool need_msi_steer;
struct iproc_msi *msi;
};
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
index 35936409b2d4..734ba0d4a5c8 100644
--- a/drivers/pci/host/pcie-qcom.c
+++ b/drivers/pci/host/pcie-qcom.c
@@ -36,11 +36,17 @@
#include "pcie-designware.h"
+#define PCIE20_PARF_SYS_CTRL 0x00
#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_SLV_ADDR_SPACE_SIZE 0x16C
+#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174
#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178
+#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
+#define PCIE20_PARF_LTSSM 0x1B0
+#define PCIE20_PARF_SID_OFFSET 0x234
+#define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C
#define PCIE20_ELBI_SYS_CTRL 0x04
#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)
@@ -72,9 +78,18 @@ struct qcom_pcie_resources_v1 {
struct regulator *vdda;
};
+struct qcom_pcie_resources_v2 {
+ struct clk *aux_clk;
+ struct clk *master_clk;
+ struct clk *slave_clk;
+ struct clk *cfg_clk;
+ struct clk *pipe_clk;
+};
+
union qcom_pcie_resources {
struct qcom_pcie_resources_v0 v0;
struct qcom_pcie_resources_v1 v1;
+ struct qcom_pcie_resources_v2 v2;
};
struct qcom_pcie;
@@ -82,7 +97,9 @@ struct qcom_pcie;
struct qcom_pcie_ops {
int (*get_resources)(struct qcom_pcie *pcie);
int (*init)(struct qcom_pcie *pcie);
+ int (*post_init)(struct qcom_pcie *pcie);
void (*deinit)(struct qcom_pcie *pcie);
+ void (*ltssm_enable)(struct qcom_pcie *pcie);
};
struct qcom_pcie {
@@ -116,17 +133,35 @@ static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
return dw_handle_msi_irq(pp);
}
-static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
+static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie)
{
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);
+}
+
+static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie)
+{
+ u32 val;
+
+ /* enable link training */
+ val = readl(pcie->parf + PCIE20_PARF_LTSSM);
+ val |= BIT(8);
+ writel(val, pcie->parf + PCIE20_PARF_LTSSM);
+}
+
+static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
+{
+
+ if (dw_pcie_link_up(&pcie->pp))
+ return 0;
+
+ /* Enable Link Training state machine */
+ if (pcie->ops->ltssm_enable)
+ pcie->ops->ltssm_enable(pcie);
return dw_pcie_wait_for_link(&pcie->pp);
}
@@ -421,6 +456,113 @@ err_res:
return ret;
}
+static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
+ struct device *dev = pcie->pp.dev;
+
+ res->aux_clk = devm_clk_get(dev, "aux");
+ if (IS_ERR(res->aux_clk))
+ return PTR_ERR(res->aux_clk);
+
+ res->cfg_clk = devm_clk_get(dev, "cfg");
+ if (IS_ERR(res->cfg_clk))
+ return PTR_ERR(res->cfg_clk);
+
+ res->master_clk = devm_clk_get(dev, "bus_master");
+ if (IS_ERR(res->master_clk))
+ return PTR_ERR(res->master_clk);
+
+ res->slave_clk = devm_clk_get(dev, "bus_slave");
+ if (IS_ERR(res->slave_clk))
+ return PTR_ERR(res->slave_clk);
+
+ res->pipe_clk = devm_clk_get(dev, "pipe");
+ if (IS_ERR(res->pipe_clk))
+ return PTR_ERR(res->pipe_clk);
+
+ return 0;
+}
+
+static int qcom_pcie_init_v2(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
+ struct device *dev = pcie->pp.dev;
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(res->aux_clk);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable aux clock\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(res->cfg_clk);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable cfg clock\n");
+ goto err_cfg_clk;
+ }
+
+ ret = clk_prepare_enable(res->master_clk);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable master clock\n");
+ goto err_master_clk;
+ }
+
+ ret = clk_prepare_enable(res->slave_clk);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable slave clock\n");
+ goto err_slave_clk;
+ }
+
+ /* enable PCIe clocks and resets */
+ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+ val &= ~BIT(0);
+ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+ /* change DBI base address */
+ writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+
+ /* MAC PHY_POWERDOWN MUX DISABLE */
+ val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
+ val &= ~BIT(29);
+ writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
+
+ val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+ val |= BIT(4);
+ writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+
+ val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+ val |= BIT(31);
+ writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+
+ return 0;
+
+err_slave_clk:
+ clk_disable_unprepare(res->master_clk);
+err_master_clk:
+ clk_disable_unprepare(res->cfg_clk);
+err_cfg_clk:
+ clk_disable_unprepare(res->aux_clk);
+
+ return ret;
+}
+
+static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
+ struct device *dev = pcie->pp.dev;
+ int ret;
+
+ ret = clk_prepare_enable(res->pipe_clk);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable pipe clock\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int qcom_pcie_link_up(struct pcie_port *pp)
{
struct qcom_pcie *pcie = to_qcom_pcie(pp);
@@ -429,6 +571,17 @@ static int qcom_pcie_link_up(struct pcie_port *pp)
return !!(val & PCI_EXP_LNKSTA_DLLLA);
}
+static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
+
+ clk_disable_unprepare(res->pipe_clk);
+ clk_disable_unprepare(res->slave_clk);
+ clk_disable_unprepare(res->master_clk);
+ clk_disable_unprepare(res->cfg_clk);
+ clk_disable_unprepare(res->aux_clk);
+}
+
static void qcom_pcie_host_init(struct pcie_port *pp)
{
struct qcom_pcie *pcie = to_qcom_pcie(pp);
@@ -444,6 +597,9 @@ static void qcom_pcie_host_init(struct pcie_port *pp)
if (ret)
goto err_deinit;
+ if (pcie->ops->post_init)
+ pcie->ops->post_init(pcie);
+
dw_pcie_setup_rc(pp);
if (IS_ENABLED(CONFIG_PCI_MSI))
@@ -487,12 +643,22 @@ 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,
+ .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable,
};
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,
+ .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable,
+};
+
+static const struct qcom_pcie_ops ops_v2 = {
+ .get_resources = qcom_pcie_get_resources_v2,
+ .init = qcom_pcie_init_v2,
+ .post_init = qcom_pcie_post_init_v2,
+ .deinit = qcom_pcie_deinit_v2,
+ .ltssm_enable = qcom_pcie_v2_ltssm_enable,
};
static int qcom_pcie_probe(struct platform_device *pdev)
@@ -572,6 +738,7 @@ 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 },
+ { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 },
{ }
};
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 62700d1896f4..aca85be101f8 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -1071,13 +1071,14 @@ 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-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-rcar-gen2",
+ .data = rcar_pcie_hw_init_gen2 },
{ .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init },
+ { .compatible = "renesas,pcie-rcar-gen3", .data = rcar_pcie_hw_init },
{},
};
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index e04f69beb42d..f2dca7bb0b39 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -53,6 +53,7 @@
#define PCIE_CLIENT_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008)
#define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x))
#define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040)
+#define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0)
#define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080)
#define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48)
#define PCIE_CLIENT_LINK_STATUS_UP 0x00300000
@@ -135,13 +136,14 @@
#define PCIE_RC_CONFIG_VENDOR (PCIE_RC_CONFIG_BASE + 0x00)
#define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08)
#define PCIE_RC_CONFIG_SCC_SHIFT 16
+#define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4)
+#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18
+#define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff
+#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26
#define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0)
-#define PCIE_RC_CONFIG_LCS_RETRAIN_LINK BIT(5)
-#define PCIE_RC_CONFIG_LCS_LBMIE BIT(10)
-#define PCIE_RC_CONFIG_LCS_LABIE BIT(11)
-#define PCIE_RC_CONFIG_LCS_LBMS BIT(30)
-#define PCIE_RC_CONFIG_LCS_LAMS BIT(31)
#define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
+#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)
+#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20)
#define PCIE_CORE_AXI_CONF_BASE 0xc00000
#define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0)
@@ -203,8 +205,14 @@ struct rockchip_pcie {
struct gpio_desc *ep_gpio;
u32 lanes;
u8 root_bus_nr;
+ int link_gen;
struct device *dev;
struct irq_domain *irq_domain;
+ u32 io_size;
+ int offset;
+ phys_addr_t io_bus_addr;
+ u32 mem_size;
+ phys_addr_t mem_bus_addr;
};
static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
@@ -223,7 +231,7 @@ static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip)
u32 status;
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
- status |= (PCIE_RC_CONFIG_LCS_LBMIE | PCIE_RC_CONFIG_LCS_LABIE);
+ status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
}
@@ -232,7 +240,7 @@ static void rockchip_pcie_clr_bw_int(struct rockchip_pcie *rockchip)
u32 status;
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
- status |= (PCIE_RC_CONFIG_LCS_LBMS | PCIE_RC_CONFIG_LCS_LAMS);
+ status |= (PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS) << 16;
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
}
@@ -398,6 +406,40 @@ static struct pci_ops rockchip_pcie_ops = {
.write = rockchip_pcie_wr_conf,
};
+static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
+{
+ u32 status, curr, scale, power;
+
+ if (IS_ERR(rockchip->vpcie3v3))
+ return;
+
+ /*
+ * Set RC's captured slot power limit and scale if
+ * vpcie3v3 available. The default values are both zero
+ * which means the software should set these two according
+ * to the actual power supply.
+ */
+ curr = regulator_get_current_limit(rockchip->vpcie3v3);
+ if (curr > 0) {
+ scale = 3; /* 0.001x */
+ curr = curr / 1000; /* convert to mA */
+ power = (curr * 3300) / 1000; /* milliwatt */
+ while (power > PCIE_RC_CONFIG_DCR_CSPL_LIMIT) {
+ if (!scale) {
+ dev_warn(rockchip->dev, "invalid power supply\n");
+ return;
+ }
+ scale--;
+ power = power / 10;
+ }
+
+ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCR);
+ status |= (power << PCIE_RC_CONFIG_DCR_CSPL_SHIFT) |
+ (scale << PCIE_RC_CONFIG_DCR_CPLS_SHIFT);
+ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR);
+ }
+}
+
/**
* rockchip_pcie_init_port - Initialize hardware
* @rockchip: PCIe port information
@@ -429,26 +471,6 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
return err;
}
- udelay(10);
-
- err = reset_control_deassert(rockchip->pm_rst);
- if (err) {
- dev_err(dev, "deassert pm_rst err %d\n", err);
- return err;
- }
-
- err = reset_control_deassert(rockchip->aclk_rst);
- if (err) {
- dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
- return err;
- }
-
- err = reset_control_deassert(rockchip->pclk_rst);
- if (err) {
- dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
- return err;
- }
-
err = phy_init(rockchip->phy);
if (err < 0) {
dev_err(dev, "fail to init phy, err %d\n", err);
@@ -479,14 +501,40 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
return err;
}
+ udelay(10);
+
+ err = reset_control_deassert(rockchip->pm_rst);
+ if (err) {
+ dev_err(dev, "deassert pm_rst err %d\n", err);
+ return err;
+ }
+
+ err = reset_control_deassert(rockchip->aclk_rst);
+ if (err) {
+ dev_err(dev, "deassert aclk_rst err %d\n", err);
+ return err;
+ }
+
+ err = reset_control_deassert(rockchip->pclk_rst);
+ if (err) {
+ dev_err(dev, "deassert pclk_rst err %d\n", err);
+ return err;
+ }
+
+ if (rockchip->link_gen == 2)
+ rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
+ PCIE_CLIENT_CONFIG);
+ else
+ rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
+ PCIE_CLIENT_CONFIG);
+
rockchip_pcie_write(rockchip,
PCIE_CLIENT_CONF_ENABLE |
PCIE_CLIENT_LINK_TRAIN_ENABLE |
PCIE_CLIENT_ARI_ENABLE |
PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes) |
- PCIE_CLIENT_MODE_RC |
- PCIE_CLIENT_GEN_SEL_2,
- PCIE_CLIENT_CONFIG);
+ PCIE_CLIENT_MODE_RC,
+ PCIE_CLIENT_CONFIG);
err = phy_power_on(rockchip->phy);
if (err) {
@@ -522,21 +570,19 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
return err;
}
- /*
- * We need to read/write PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 before
- * enabling ASPM. Otherwise L1PwrOnSc and L1PwrOnVal isn't
- * reliable and enabling ASPM doesn't work. This is a controller
- * bug we need to work around.
- */
- status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2);
- rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2);
-
/* Fix the transmitted FTS count desired to exit from L0s. */
status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL_PLC1);
- status = (status & PCIE_CORE_CTRL_PLC1_FTS_MASK) |
+ status = (status & ~PCIE_CORE_CTRL_PLC1_FTS_MASK) |
(PCIE_CORE_CTRL_PLC1_FTS_CNT << PCIE_CORE_CTRL_PLC1_FTS_SHIFT);
rockchip_pcie_write(rockchip, status, PCIE_CORE_CTRL_PLC1);
+ rockchip_pcie_set_power_limit(rockchip);
+
+ /* Set RC's clock architecture as common clock */
+ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
+ status |= PCI_EXP_LNKCTL_CCC;
+ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
+
/* Enable Gen1 training */
rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
PCIE_CLIENT_CONFIG);
@@ -563,35 +609,37 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
msleep(20);
}
- /*
- * Enable retrain for gen2. This should be configured only after
- * gen1 finished.
- */
- status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
- status |= PCIE_RC_CONFIG_LCS_RETRAIN_LINK;
- rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
+ if (rockchip->link_gen == 2) {
+ /*
+ * Enable retrain for gen2. This should be configured only after
+ * gen1 finished.
+ */
+ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
+ status |= PCI_EXP_LNKCTL_RL;
+ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
+
+ timeout = jiffies + msecs_to_jiffies(500);
+ for (;;) {
+ status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL);
+ if ((status & PCIE_CORE_PL_CONF_SPEED_MASK) ==
+ PCIE_CORE_PL_CONF_SPEED_5G) {
+ dev_dbg(dev, "PCIe link training gen2 pass!\n");
+ break;
+ }
- timeout = jiffies + msecs_to_jiffies(500);
- for (;;) {
- status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL);
- if ((status & PCIE_CORE_PL_CONF_SPEED_MASK) ==
- PCIE_CORE_PL_CONF_SPEED_5G) {
- dev_dbg(dev, "PCIe link training gen2 pass!\n");
- break;
- }
+ if (time_after(jiffies, timeout)) {
+ dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n");
+ break;
+ }
- if (time_after(jiffies, timeout)) {
- dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n");
- break;
+ msleep(20);
}
-
- msleep(20);
}
/* Check the final link width from negotiated lane counter from MGMT */
status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL);
- status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >>
- PCIE_CORE_PL_CONF_LANE_MASK);
+ status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >>
+ PCIE_CORE_PL_CONF_LANE_SHIFT);
dev_dbg(dev, "current link width is x%d\n", status);
rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID,
@@ -599,6 +647,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
rockchip_pcie_write(rockchip,
PCI_CLASS_BRIDGE_PCI << PCIE_RC_CONFIG_SCC_SHIFT,
PCIE_RC_CONFIG_RID_CCR);
+
+ /* Clear THP cap's next cap pointer to remove L1 substate cap */
+ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_THP_CAP);
+ status &= ~PCIE_RC_CONFIG_THP_CAP_NEXT_MASK;
+ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_THP_CAP);
+
rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF);
rockchip_pcie_write(rockchip,
@@ -794,6 +848,10 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
rockchip->lanes = 1;
}
+ rockchip->link_gen = of_pci_get_max_link_speed(node);
+ if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
+ rockchip->link_gen = 2;
+
rockchip->core_rst = devm_reset_control_get(dev, "core");
if (IS_ERR(rockchip->core_rst)) {
if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
@@ -1087,6 +1145,50 @@ static int rockchip_pcie_prog_ib_atu(struct rockchip_pcie *rockchip,
return 0;
}
+static int rockchip_cfg_atu(struct rockchip_pcie *rockchip)
+{
+ struct device *dev = rockchip->dev;
+ int offset;
+ int err;
+ int reg_no;
+
+ for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) {
+ err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1,
+ AXI_WRAPPER_MEM_WRITE,
+ 20 - 1,
+ rockchip->mem_bus_addr +
+ (reg_no << 20),
+ 0);
+ if (err) {
+ dev_err(dev, "program RC mem outbound ATU failed\n");
+ return err;
+ }
+ }
+
+ err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0);
+ if (err) {
+ dev_err(dev, "program RC mem inbound ATU failed\n");
+ return err;
+ }
+
+ offset = rockchip->mem_size >> 20;
+ for (reg_no = 0; reg_no < (rockchip->io_size >> 20); reg_no++) {
+ err = rockchip_pcie_prog_ob_atu(rockchip,
+ reg_no + 1 + offset,
+ AXI_WRAPPER_IO_WRITE,
+ 20 - 1,
+ rockchip->io_bus_addr +
+ (reg_no << 20),
+ 0);
+ if (err) {
+ dev_err(dev, "program RC io outbound ATU failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
static int rockchip_pcie_probe(struct platform_device *pdev)
{
struct rockchip_pcie *rockchip;
@@ -1096,13 +1198,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
resource_size_t io_base;
struct resource *mem;
struct resource *io;
- phys_addr_t io_bus_addr = 0;
- u32 io_size;
- phys_addr_t mem_bus_addr = 0;
- u32 mem_size = 0;
- int reg_no;
int err;
- int offset;
LIST_HEAD(res);
@@ -1169,14 +1265,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
goto err_vpcie;
/* Get the I/O and memory ranges from DT */
- io_size = 0;
resource_list_for_each_entry(win, &res) {
switch (resource_type(win->res)) {
case IORESOURCE_IO:
io = win->res;
io->name = "I/O";
- io_size = resource_size(io);
- io_bus_addr = io->start - win->offset;
+ rockchip->io_size = resource_size(io);
+ rockchip->io_bus_addr = io->start - win->offset;
err = pci_remap_iospace(io, io_base);
if (err) {
dev_warn(dev, "error %d: failed to map resource %pR\n",
@@ -1187,8 +1282,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
case IORESOURCE_MEM:
mem = win->res;
mem->name = "MEM";
- mem_size = resource_size(mem);
- mem_bus_addr = mem->start - win->offset;
+ rockchip->mem_size = resource_size(mem);
+ rockchip->mem_bus_addr = mem->start - win->offset;
break;
case IORESOURCE_BUS:
rockchip->root_bus_nr = win->res->start;
@@ -1198,45 +1293,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
}
}
- if (mem_size) {
- for (reg_no = 0; reg_no < (mem_size >> 20); reg_no++) {
- err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1,
- AXI_WRAPPER_MEM_WRITE,
- 20 - 1,
- mem_bus_addr +
- (reg_no << 20),
- 0);
- if (err) {
- dev_err(dev, "program RC mem outbound ATU failed\n");
- goto err_vpcie;
- }
- }
- }
-
- err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0);
- if (err) {
- dev_err(dev, "program RC mem inbound ATU failed\n");
+ err = rockchip_cfg_atu(rockchip);
+ if (err)
goto err_vpcie;
- }
-
- offset = mem_size >> 20;
-
- if (io_size) {
- for (reg_no = 0; reg_no < (io_size >> 20); reg_no++) {
- err = rockchip_pcie_prog_ob_atu(rockchip,
- reg_no + 1 + offset,
- AXI_WRAPPER_IO_WRITE,
- 20 - 1,
- io_bus_addr +
- (reg_no << 20),
- 0);
- if (err) {
- dev_err(dev, "program RC io outbound ATU failed\n");
- goto err_vpcie;
- }
- }
- }
-
bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res);
if (!bus) {
err = -ENOMEM;
@@ -1249,9 +1308,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
pcie_bus_configure_settings(child);
pci_bus_add_devices(bus);
-
- dev_warn(dev, "only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields\n");
-
return err;
err_vpcie:
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index 3cf197ba7f37..dafe8b88d97d 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -296,8 +296,4 @@ static struct platform_driver spear13xx_pcie_driver = {
},
};
-static int __init spear13xx_pcie_init(void)
-{
- return platform_driver_register(&spear13xx_pcie_driver);
-}
-device_initcall(spear13xx_pcie_init);
+builtin_platform_driver(spear13xx_pcie_driver);
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c
index 37e29b580be3..18ef1a93c10a 100644
--- a/drivers/pci/host/vmd.c
+++ b/drivers/pci/host/vmd.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/pci.h>
+#include <linux/srcu.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -39,7 +40,6 @@ 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.
* @enabled: true if driver enabled IRQ
* @virq: the virtual IRQ value provided to the requesting driver.
@@ -49,7 +49,6 @@ static DEFINE_RAW_SPINLOCK(list_lock);
*/
struct vmd_irq {
struct list_head node;
- struct rcu_head rcu;
struct vmd_irq_list *irq;
bool enabled;
unsigned int virq;
@@ -58,11 +57,13 @@ struct vmd_irq {
/**
* 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.
+ * @srcu: SRCU struct for local synchronization.
* @count: number of child IRQs assigned to this vector; used to track
* sharing.
*/
struct vmd_irq_list {
struct list_head irq_list;
+ struct srcu_struct srcu;
unsigned int count;
};
@@ -224,14 +225,14 @@ static void vmd_msi_free(struct irq_domain *domain,
struct vmd_irq *vmdirq = irq_get_chip_data(virq);
unsigned long flags;
- synchronize_rcu();
+ synchronize_srcu(&vmdirq->irq->srcu);
/* XXX: Potential optimization to rebalance */
raw_spin_lock_irqsave(&list_lock, flags);
vmdirq->irq->count--;
raw_spin_unlock_irqrestore(&list_lock, flags);
- kfree_rcu(vmdirq, rcu);
+ kfree(vmdirq);
}
static int vmd_msi_prepare(struct irq_domain *domain, struct device *dev,
@@ -646,11 +647,12 @@ static irqreturn_t vmd_irq(int irq, void *data)
{
struct vmd_irq_list *irqs = data;
struct vmd_irq *vmdirq;
+ int idx;
- rcu_read_lock();
+ idx = srcu_read_lock(&irqs->srcu);
list_for_each_entry_rcu(vmdirq, &irqs->irq_list, node)
generic_handle_irq(vmdirq->virq);
- rcu_read_unlock();
+ srcu_read_unlock(&irqs->srcu, idx);
return IRQ_HANDLED;
}
@@ -696,6 +698,10 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENOMEM;
for (i = 0; i < vmd->msix_count; i++) {
+ err = init_srcu_struct(&vmd->irqs[i].srcu);
+ if (err)
+ return err;
+
INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i),
vmd_irq, 0, "vmd", &vmd->irqs[i]);
@@ -714,12 +720,20 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
return 0;
}
+static void vmd_cleanup_srcu(struct vmd_dev *vmd)
+{
+ int i;
+
+ for (i = 0; i < vmd->msix_count; i++)
+ cleanup_srcu_struct(&vmd->irqs[i].srcu);
+}
+
static void vmd_remove(struct pci_dev *dev)
{
struct vmd_dev *vmd = pci_get_drvdata(dev);
vmd_detach_resources(vmd);
- pci_set_drvdata(dev, NULL);
+ vmd_cleanup_srcu(vmd);
sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
pci_stop_root_bus(vmd->bus);
pci_remove_root_bus(vmd->bus);
@@ -727,7 +741,7 @@ static void vmd_remove(struct pci_dev *dev)
irq_domain_remove(vmd->irq_domain);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int vmd_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a46b585fae31..5ed2dcaa8e27 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -222,35 +222,6 @@ static void acpiphp_post_dock_fixup(struct acpi_device *adev)
acpiphp_let_context_go(context);
}
-/* Check whether the PCI device is managed by native PCIe hotplug driver */
-static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
-{
- u32 reg32;
- acpi_handle tmp;
- struct acpi_pci_root *root;
-
- /* Check whether the PCIe port supports native PCIe hotplug */
- if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32))
- return false;
- if (!(reg32 & PCI_EXP_SLTCAP_HPC))
- return false;
-
- /*
- * Check whether native PCIe hotplug has been enabled for
- * this PCIe hierarchy.
- */
- tmp = acpi_find_root_bridge_handle(pdev);
- if (!tmp)
- return false;
- root = acpi_pci_find_root(tmp);
- if (!root)
- return false;
- if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
- return false;
-
- return true;
-}
-
/**
* acpiphp_add_context - Add ACPIPHP context to an ACPI device object.
* @handle: ACPI handle of the object to add a context to.
@@ -334,7 +305,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
* expose slots to user space in those cases.
*/
if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev))
- && !(pdev && device_is_managed_by_native_pciehp(pdev))) {
+ && !(pdev && pdev->is_hotplug_bridge && pciehp_is_native(pdev))) {
unsigned long long sun;
int retval;
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 74f3a0695b43..ec009a7dba20 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -867,7 +867,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) {
err(msg_HPC_not_supported);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err_disable_device;
}
/* TODO: This code can be made to support non-Compaq or Intel
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index fea0b8b33589..56013d0daf7f 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -23,6 +23,9 @@
*
* Send feedback to <kristen.c.accardi@intel.com>
*
+ * Authors:
+ * Greg Kroah-Hartman <greg@kroah.com>
+ * Scott Murray <scottm@somanetworks.com>
*/
#include <linux/module.h> /* try_module_get & module_put */
@@ -50,15 +53,9 @@
#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 */
static bool debug;
-#define DRIVER_VERSION "0.5"
-#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
-#define DRIVER_DESC "PCI Hot Plug PCI Core"
-
-
static LIST_HEAD(pci_hotplug_slot_list);
static DEFINE_MUTEX(pci_hp_mutex);
@@ -534,7 +531,6 @@ static int __init pci_hotplug_init(void)
return result;
}
- info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
return result;
}
device_initcall(pci_hotplug_init);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7d32fa33dcef..35d84845d5af 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -25,6 +25,10 @@
*
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
+ * Authors:
+ * Dan Zink <dan.zink@compaq.com>
+ * Greg Kroah-Hartman <greg@kroah.com>
+ * Dely Sy <dely.l.sy@intel.com>"
*/
#include <linux/moduleparam.h>
@@ -42,10 +46,6 @@ bool pciehp_poll_mode;
int pciehp_poll_time;
static bool pciehp_force;
-#define DRIVER_VERSION "0.4"
-#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
-#define DRIVER_DESC "PCI Express Hot Plug Controller Driver"
-
/*
* not really modular, but the easiest way to keep compat with existing
* bootargs behaviour is to continue using module_param here.
@@ -333,7 +333,6 @@ static int __init pcied_init(void)
retval = pcie_port_service_register(&hpdriver_portdrv);
dbg("pcie_port_service_register = %d\n", retval);
- info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
if (retval)
dbg("Failure to register service\n");
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index efe69e879455..10c9c0ba8ff2 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <linux/pci.h>
#include "../pci.h"
#include "pciehp.h"
@@ -98,6 +99,7 @@ static int board_added(struct slot *p_slot)
pciehp_green_led_blink(p_slot);
/* Check link training status */
+ pm_runtime_get_sync(&ctrl->pcie->port->dev);
retval = pciehp_check_link_status(ctrl);
if (retval) {
ctrl_err(ctrl, "Failed to check link status\n");
@@ -118,12 +120,14 @@ static int board_added(struct slot *p_slot)
if (retval != -EEXIST)
goto err_exit;
}
+ pm_runtime_put(&ctrl->pcie->port->dev);
pciehp_green_led_on(p_slot);
pciehp_set_attention_status(p_slot, 0);
return 0;
err_exit:
+ pm_runtime_put(&ctrl->pcie->port->dev);
set_slot_off(ctrl, p_slot);
return retval;
}
@@ -137,7 +141,9 @@ static int remove_board(struct slot *p_slot)
int retval;
struct controller *ctrl = p_slot->ctrl;
+ pm_runtime_get_sync(&ctrl->pcie->port->dev);
retval = pciehp_unconfigure_device(p_slot);
+ pm_runtime_put(&ctrl->pcie->port->dev);
if (retval)
return retval;
@@ -410,7 +416,7 @@ int pciehp_enable_slot(struct slot *p_slot)
if (getstatus) {
ctrl_info(ctrl, "Slot(%s): Already enabled\n",
slot_name(p_slot));
- return -EINVAL;
+ return 0;
}
}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index b57fc6d6e28a..026830a138ae 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -620,8 +620,18 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
}
- /* Check Presence Detect Changed */
- if (events & PCI_EXP_SLTSTA_PDC) {
+ /*
+ * Check Link Status Changed at higher precedence than Presence
+ * Detect Changed. The PDS value may be set to "card present" from
+ * out-of-band detection, which may be in conflict with a Link Down
+ * and cause the wrong event to queue.
+ */
+ if (events & PCI_EXP_SLTSTA_DLLSC) {
+ ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot),
+ link ? "Up" : "Down");
+ pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP :
+ INT_LINK_DOWN);
+ } else if (events & PCI_EXP_SLTSTA_PDC) {
present = !!(status & PCI_EXP_SLTSTA_PDS);
ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot),
present ? "" : "not ");
@@ -636,13 +646,6 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
pciehp_queue_interrupt_event(slot, INT_POWER_FAULT);
}
- if (events & PCI_EXP_SLTSTA_DLLSC) {
- ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot),
- link ? "Up" : "Down");
- pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP :
- INT_LINK_DOWN);
- }
-
return IRQ_HANDLED;
}
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index e30f05c8517f..47227820406d 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -306,13 +306,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
return rc;
}
- pci_iov_set_numvfs(dev, nr_virtfn);
- iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
- pci_cfg_access_lock(dev);
- pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
- msleep(100);
- pci_cfg_access_unlock(dev);
-
iov->initial_VFs = initial;
if (nr_virtfn < initial)
initial = nr_virtfn;
@@ -323,6 +316,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
goto err_pcibios;
}
+ pci_iov_set_numvfs(dev, nr_virtfn);
+ iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
+ pci_cfg_access_lock(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ msleep(100);
+ pci_cfg_access_unlock(dev);
+
for (i = 0; i < initial; i++) {
rc = pci_iov_add_virtfn(dev, i, 0);
if (rc)
@@ -554,21 +554,61 @@ void pci_iov_release(struct pci_dev *dev)
}
/**
- * pci_iov_resource_bar - get position of the SR-IOV BAR
+ * pci_iov_update_resource - update a VF BAR
* @dev: the PCI device
* @resno: the resource number
*
- * Returns position of the BAR encapsulated in the SR-IOV capability.
+ * Update a VF BAR in the SR-IOV capability of a PF.
*/
-int pci_iov_resource_bar(struct pci_dev *dev, int resno)
+void pci_iov_update_resource(struct pci_dev *dev, int resno)
{
- if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
- return 0;
+ struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL;
+ struct resource *res = dev->resource + resno;
+ int vf_bar = resno - PCI_IOV_RESOURCES;
+ struct pci_bus_region region;
+ u16 cmd;
+ u32 new;
+ int reg;
+
+ /*
+ * The generic pci_restore_bars() path calls this for all devices,
+ * including VFs and non-SR-IOV devices. If this is not a PF, we
+ * have nothing to do.
+ */
+ if (!iov)
+ return;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &cmd);
+ if ((cmd & PCI_SRIOV_CTRL_VFE) && (cmd & PCI_SRIOV_CTRL_MSE)) {
+ dev_WARN(&dev->dev, "can't update enabled VF BAR%d %pR\n",
+ vf_bar, res);
+ return;
+ }
+
+ /*
+ * Ignore unimplemented BARs, unused resource slots for 64-bit
+ * BARs, and non-movable resources, e.g., those described via
+ * Enhanced Allocation.
+ */
+ if (!res->flags)
+ return;
+
+ if (res->flags & IORESOURCE_UNSET)
+ return;
+
+ if (res->flags & IORESOURCE_PCI_FIXED)
+ return;
- BUG_ON(!dev->is_physfn);
+ pcibios_resource_to_bus(dev->bus, &region, res);
+ new = region.start;
+ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
- return dev->sriov->pos + PCI_SRIOV_BAR +
- 4 * (resno - PCI_IOV_RESOURCES);
+ reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar;
+ pci_write_config_dword(dev, reg, new);
+ if (res->flags & IORESOURCE_MEM_64) {
+ new = region.start >> 16 >> 16;
+ pci_write_config_dword(dev, reg + 4, new);
+ }
}
resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev,
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index dd27f73a45fc..50c5003295ca 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1302,7 +1302,8 @@ const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr)
} else if (dev->msi_enabled) {
struct msi_desc *entry = first_pci_msi_entry(dev);
- if (WARN_ON_ONCE(!entry || nr >= entry->nvec_used))
+ if (WARN_ON_ONCE(!entry || !entry->affinity ||
+ nr >= entry->nvec_used))
return NULL;
return &entry->affinity[nr];
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index d966d47c9e80..001860361434 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -29,6 +29,82 @@ const u8 pci_acpi_dsm_uuid[] = {
0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d
};
+#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
+static int acpi_get_rc_addr(struct acpi_device *adev, struct resource *res)
+{
+ struct device *dev = &adev->dev;
+ struct resource_entry *entry;
+ struct list_head list;
+ unsigned long flags;
+ int ret;
+
+ INIT_LIST_HEAD(&list);
+ flags = IORESOURCE_MEM;
+ ret = acpi_dev_get_resources(adev, &list,
+ acpi_dev_filter_resource_type_cb,
+ (void *) flags);
+ if (ret < 0) {
+ dev_err(dev, "failed to parse _CRS method, error code %d\n",
+ ret);
+ return ret;
+ }
+
+ if (ret == 0) {
+ dev_err(dev, "no IO and memory resources present in _CRS\n");
+ return -EINVAL;
+ }
+
+ entry = list_first_entry(&list, struct resource_entry, node);
+ *res = *entry->res;
+ acpi_dev_free_resource_list(&list);
+ return 0;
+}
+
+static acpi_status acpi_match_rc(acpi_handle handle, u32 lvl, void *context,
+ void **retval)
+{
+ u16 *segment = context;
+ unsigned long long uid;
+ acpi_status status;
+
+ status = acpi_evaluate_integer(handle, "_UID", NULL, &uid);
+ if (ACPI_FAILURE(status) || uid != *segment)
+ return AE_CTRL_DEPTH;
+
+ *(acpi_handle *)retval = handle;
+ return AE_CTRL_TERMINATE;
+}
+
+int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
+ struct resource *res)
+{
+ struct acpi_device *adev;
+ acpi_status status;
+ acpi_handle handle;
+ int ret;
+
+ status = acpi_get_devices(hid, acpi_match_rc, &segment, &handle);
+ if (ACPI_FAILURE(status)) {
+ dev_err(dev, "can't find _HID %s device to locate resources\n",
+ hid);
+ return -ENODEV;
+ }
+
+ ret = acpi_bus_get_device(handle, &adev);
+ if (ret)
+ return ret;
+
+ ret = acpi_get_rc_addr(adev, res);
+ if (ret) {
+ dev_err(dev, "can't get resource from %s\n",
+ dev_name(&adev->dev));
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
{
acpi_status status = AE_NOT_EXIST;
@@ -294,6 +370,30 @@ int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp)
EXPORT_SYMBOL_GPL(pci_get_hp_params);
/**
+ * pciehp_is_native - Check whether a hotplug port is handled by the OS
+ * @pdev: Hotplug port to check
+ *
+ * Walk up from @pdev to the host bridge, obtain its cached _OSC Control Field
+ * and return the value of the "PCI Express Native Hot Plug control" bit.
+ * On failure to obtain the _OSC Control Field return %false.
+ */
+bool pciehp_is_native(struct pci_dev *pdev)
+{
+ struct acpi_pci_root *root;
+ acpi_handle handle;
+
+ handle = acpi_find_root_bridge_handle(pdev);
+ if (!handle)
+ return false;
+
+ root = acpi_pci_find_root(handle);
+ if (!root)
+ return false;
+
+ return root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL;
+}
+
+/**
* pci_acpi_wake_bus - Root bus wakeup notification fork function.
* @work: Work item to handle.
*/
diff --git a/drivers/pci/pci-mid.c b/drivers/pci/pci-mid.c
index c7f3408e3148..1c4af7227bca 100644
--- a/drivers/pci/pci-mid.c
+++ b/drivers/pci/pci-mid.c
@@ -54,7 +54,7 @@ static bool mid_pci_need_resume(struct pci_dev *dev)
return false;
}
-static struct pci_platform_pm_ops mid_pci_platform_pm = {
+static const struct pci_platform_pm_ops mid_pci_platform_pm = {
.is_manageable = mid_pci_power_manageable,
.set_state = mid_pci_set_power_state,
.get_state = mid_pci_get_power_state,
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index bcd10c795284..066628776e1b 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -50,6 +50,7 @@ pci_config_attr(vendor, "0x%04x\n");
pci_config_attr(device, "0x%04x\n");
pci_config_attr(subsystem_vendor, "0x%04x\n");
pci_config_attr(subsystem_device, "0x%04x\n");
+pci_config_attr(revision, "0x%02x\n");
pci_config_attr(class, "0x%06x\n");
pci_config_attr(irq, "%u\n");
@@ -568,6 +569,7 @@ static struct attribute *pci_dev_attrs[] = {
&dev_attr_device.attr,
&dev_attr_subsystem_vendor.attr,
&dev_attr_subsystem_device.attr,
+ &dev_attr_revision.attr,
&dev_attr_class.attr,
&dev_attr_irq.attr,
&dev_attr_local_cpus.attr,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index ba34907538f6..a881c0d3d2e8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -564,10 +564,6 @@ static void pci_restore_bars(struct pci_dev *dev)
{
int i;
- /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
- if (dev->is_virtfn)
- return;
-
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
pci_update_resource(dev, i);
}
@@ -2106,6 +2102,10 @@ bool pci_dev_run_wake(struct pci_dev *dev)
if (!dev->pme_support)
return false;
+ /* PME-capable in principle, but not from the intended sleep state */
+ if (!pci_pme_capable(dev, pci_target_state(dev)))
+ return false;
+
while (bus->parent) {
struct pci_dev *bridge = bus->self;
@@ -2226,7 +2226,7 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev)
* This function checks if it is possible to move the bridge to D3.
* Currently we only allow D3 for recent enough PCIe ports.
*/
-static bool pci_bridge_d3_possible(struct pci_dev *bridge)
+bool pci_bridge_d3_possible(struct pci_dev *bridge)
{
unsigned int year;
@@ -2239,6 +2239,14 @@ static bool pci_bridge_d3_possible(struct pci_dev *bridge)
case PCI_EXP_TYPE_DOWNSTREAM:
if (pci_bridge_d3_disable)
return false;
+
+ /*
+ * Hotplug ports handled by firmware in System Management Mode
+ * may not be put into D3 by the OS (Thunderbolt on non-Macs).
+ */
+ if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge))
+ return false;
+
if (pci_bridge_d3_force)
return true;
@@ -2259,32 +2267,36 @@ static bool pci_bridge_d3_possible(struct pci_dev *bridge)
static int pci_dev_check_d3cold(struct pci_dev *dev, void *data)
{
bool *d3cold_ok = data;
- bool no_d3cold;
- /*
- * The device needs to be allowed to go D3cold and if it is wake
- * capable to do so from D3cold.
- */
- no_d3cold = dev->no_d3cold || !dev->d3cold_allowed ||
- (device_may_wakeup(&dev->dev) && !pci_pme_capable(dev, PCI_D3cold)) ||
- !pci_power_manageable(dev);
+ if (/* The device needs to be allowed to go D3cold ... */
+ dev->no_d3cold || !dev->d3cold_allowed ||
- *d3cold_ok = !no_d3cold;
+ /* ... and if it is wakeup capable to do so from D3cold. */
+ (device_may_wakeup(&dev->dev) &&
+ !pci_pme_capable(dev, PCI_D3cold)) ||
- return no_d3cold;
+ /* If it is a bridge it must be allowed to go to D3. */
+ !pci_power_manageable(dev) ||
+
+ /* Hotplug interrupts cannot be delivered if the link is down. */
+ dev->is_hotplug_bridge)
+
+ *d3cold_ok = false;
+
+ return !*d3cold_ok;
}
/*
* pci_bridge_d3_update - Update bridge D3 capabilities
* @dev: PCI device which is changed
- * @remove: Is the device being removed
*
* Update upstream bridge PM capabilities accordingly depending on if the
* device PM configuration was changed or the device is being removed. The
* change is also propagated upstream.
*/
-static void pci_bridge_d3_update(struct pci_dev *dev, bool remove)
+void pci_bridge_d3_update(struct pci_dev *dev)
{
+ bool remove = !device_is_registered(&dev->dev);
struct pci_dev *bridge;
bool d3cold_ok = true;
@@ -2292,55 +2304,39 @@ static void pci_bridge_d3_update(struct pci_dev *dev, bool remove)
if (!bridge || !pci_bridge_d3_possible(bridge))
return;
- pci_dev_get(bridge);
/*
- * If the device is removed we do not care about its D3cold
- * capabilities.
+ * If D3 is currently allowed for the bridge, removing one of its
+ * children won't change that.
+ */
+ if (remove && bridge->bridge_d3)
+ return;
+
+ /*
+ * If D3 is currently allowed for the bridge and a child is added or
+ * changed, disallowance of D3 can only be caused by that child, so
+ * we only need to check that single device, not any of its siblings.
+ *
+ * If D3 is currently not allowed for the bridge, checking the device
+ * first may allow us to skip checking its siblings.
*/
if (!remove)
pci_dev_check_d3cold(dev, &d3cold_ok);
- if (d3cold_ok) {
- /*
- * We need to go through all children to find out if all of
- * them can still go to D3cold.
- */
+ /*
+ * If D3 is currently not allowed for the bridge, this may be caused
+ * either by the device being changed/removed or any of its siblings,
+ * so we need to go through all children to find out if one of them
+ * continues to block D3.
+ */
+ if (d3cold_ok && !bridge->bridge_d3)
pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold,
&d3cold_ok);
- }
if (bridge->bridge_d3 != d3cold_ok) {
bridge->bridge_d3 = d3cold_ok;
/* Propagate change to upstream bridges */
- pci_bridge_d3_update(bridge, false);
+ pci_bridge_d3_update(bridge);
}
-
- pci_dev_put(bridge);
-}
-
-/**
- * pci_bridge_d3_device_changed - Update bridge D3 capabilities on change
- * @dev: PCI device that was changed
- *
- * If a device is added or its PM configuration, such as is it allowed to
- * enter D3cold, is changed this function updates upstream bridge PM
- * capabilities accordingly.
- */
-void pci_bridge_d3_device_changed(struct pci_dev *dev)
-{
- pci_bridge_d3_update(dev, false);
-}
-
-/**
- * pci_bridge_d3_device_removed - Update bridge D3 capabilities on remove
- * @dev: PCI device being removed
- *
- * Function updates upstream bridge PM capabilities based on other devices
- * still left on the bus.
- */
-void pci_bridge_d3_device_removed(struct pci_dev *dev)
-{
- pci_bridge_d3_update(dev, true);
}
/**
@@ -2355,7 +2351,7 @@ void pci_d3cold_enable(struct pci_dev *dev)
{
if (dev->no_d3cold) {
dev->no_d3cold = false;
- pci_bridge_d3_device_changed(dev);
+ pci_bridge_d3_update(dev);
}
}
EXPORT_SYMBOL_GPL(pci_d3cold_enable);
@@ -2372,7 +2368,7 @@ void pci_d3cold_disable(struct pci_dev *dev)
{
if (!dev->no_d3cold) {
dev->no_d3cold = true;
- pci_bridge_d3_device_changed(dev);
+ pci_bridge_d3_update(dev);
}
}
EXPORT_SYMBOL_GPL(pci_d3cold_disable);
@@ -4831,36 +4827,6 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags)
}
EXPORT_SYMBOL(pci_select_bars);
-/**
- * pci_resource_bar - get position of the BAR associated with a resource
- * @dev: the PCI device
- * @resno: the resource number
- * @type: the BAR type to be filled in
- *
- * Returns BAR position in config space, or 0 if the BAR is invalid.
- */
-int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
-{
- int reg;
-
- if (resno < PCI_ROM_RESOURCE) {
- *type = pci_bar_unknown;
- return PCI_BASE_ADDRESS_0 + 4 * resno;
- } else if (resno == PCI_ROM_RESOURCE) {
- *type = pci_bar_mem32;
- return dev->rom_base_reg;
- } else if (resno < PCI_BRIDGE_RESOURCES) {
- /* device specific resource */
- *type = pci_bar_unknown;
- reg = pci_iov_resource_bar(dev, resno);
- if (reg)
- return reg;
- }
-
- dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
- return 0;
-}
-
/* Some architectures require additional programming to enable VGA */
static arch_set_vga_state_t arch_set_vga_state;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 451856210e18..cb17db242f30 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,9 +1,6 @@
#ifndef DRIVERS_PCI_H
#define DRIVERS_PCI_H
-#define PCI_CFG_SPACE_SIZE 256
-#define PCI_CFG_SPACE_EXP_SIZE 4096
-
#define PCI_FIND_CAP_TTL 48
extern const unsigned char pcie_link_speed[];
@@ -85,8 +82,8 @@ void pci_pm_init(struct pci_dev *dev);
void pci_ea_init(struct pci_dev *dev);
void pci_allocate_cap_save_buffers(struct pci_dev *dev);
void pci_free_cap_save_buffers(struct pci_dev *dev);
-void pci_bridge_d3_device_changed(struct pci_dev *dev);
-void pci_bridge_d3_device_removed(struct pci_dev *dev);
+bool pci_bridge_d3_possible(struct pci_dev *dev);
+void pci_bridge_d3_update(struct pci_dev *dev);
static inline void pci_wakeup_event(struct pci_dev *dev)
{
@@ -245,7 +242,6 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
int pci_setup_device(struct pci_dev *dev);
int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct resource *res, unsigned int reg);
-int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type);
void pci_configure_ari(struct pci_dev *dev);
void __pci_bus_size_bridges(struct pci_bus *bus,
struct list_head *realloc_head);
@@ -289,7 +285,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
#ifdef CONFIG_PCI_IOV
int pci_iov_init(struct pci_dev *dev);
void pci_iov_release(struct pci_dev *dev);
-int pci_iov_resource_bar(struct pci_dev *dev, int resno);
+void pci_iov_update_resource(struct pci_dev *dev, int resno);
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
void pci_restore_iov_state(struct pci_dev *dev);
int pci_iov_bus_range(struct pci_bus *bus);
@@ -303,10 +299,6 @@ static inline void pci_iov_release(struct pci_dev *dev)
{
}
-static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno)
-{
- return 0;
-}
static inline void pci_restore_iov_state(struct pci_dev *dev)
{
}
@@ -356,4 +348,9 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
}
#endif
+#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
+int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
+ struct resource *res);
+#endif
+
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 139150b2bdfd..dea186a9d6b6 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -30,13 +30,6 @@
#include "aerdrv.h"
#include "../../pci.h"
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.0"
-#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
-#define DRIVER_DESC "Root Port Advanced Error Reporting Driver"
-
static int aer_probe(struct pcie_device *dev);
static void aer_remove(struct pcie_device *dev);
static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
@@ -297,12 +290,12 @@ static int aer_probe(struct pcie_device *dev)
{
int status;
struct aer_rpc *rpc;
- struct device *device = &dev->device;
+ struct device *device = &dev->port->dev;
/* Alloc rpc data structure */
rpc = aer_alloc_rpc(dev);
if (!rpc) {
- dev_printk(KERN_DEBUG, device, "alloc rpc failed\n");
+ dev_printk(KERN_DEBUG, device, "alloc AER rpc failed\n");
aer_remove(dev);
return -ENOMEM;
}
@@ -310,7 +303,8 @@ static int aer_probe(struct pcie_device *dev)
/* Request IRQ ISR */
status = request_irq(dev->irq, aer_irq, IRQF_SHARED, "aerdrv", dev);
if (status) {
- dev_printk(KERN_DEBUG, device, "request IRQ failed\n");
+ dev_printk(KERN_DEBUG, device, "request AER IRQ %d failed\n",
+ dev->irq);
aer_remove(dev);
return status;
}
@@ -318,8 +312,8 @@ static int aer_probe(struct pcie_device *dev)
rpc->isr = 1;
aer_enable_rootport(rpc);
-
- return status;
+ dev_info(device, "AER enabled with IRQ %d\n", dev->irq);
+ return 0;
}
/**
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 0ec649d961d7..17ac1dce3286 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -351,12 +351,26 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
return;
}
+ /* Get upstream/downstream components' register state */
+ pcie_get_aspm_reg(parent, &upreg);
+ child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
+ pcie_get_aspm_reg(child, &dwreg);
+
+ /*
+ * If ASPM not supported, don't mess with the clocks and link,
+ * bail out now.
+ */
+ if (!(upreg.support & dwreg.support))
+ return;
+
/* Configure common clock before checking latencies */
pcie_aspm_configure_common_clock(link);
- /* Get upstream/downstream components' register state */
+ /*
+ * Re-read upstream/downstream components' register state
+ * after clock configuration
+ */
pcie_get_aspm_reg(parent, &upreg);
- child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
pcie_get_aspm_reg(child, &dwreg);
/*
@@ -886,8 +900,8 @@ static ssize_t clk_ctl_store(struct device *dev,
return n;
}
-static DEVICE_ATTR(link_state, 0644, link_state_show, link_state_store);
-static DEVICE_ATTR(clk_ctl, 0644, clk_ctl_show, clk_ctl_store);
+static DEVICE_ATTR_RW(link_state);
+static DEVICE_ATTR_RW(clk_ctl);
static char power_group[] = "power";
void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 884bad5320f8..717529331dac 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -300,8 +300,6 @@ static irqreturn_t pcie_pme_irq(int irq, void *context)
*/
static int pcie_pme_set_native(struct pci_dev *dev, void *ign)
{
- dev_info(&dev->dev, "Signaling PME through PCIe PME interrupt\n");
-
device_set_run_wake(&dev->dev, true);
dev->pme_interrupt = true;
return 0;
@@ -319,23 +317,8 @@ static int pcie_pme_set_native(struct pci_dev *dev, void *ign)
static void pcie_pme_mark_devices(struct pci_dev *port)
{
pcie_pme_set_native(port, NULL);
- if (port->subordinate) {
+ if (port->subordinate)
pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL);
- } else {
- struct pci_bus *bus = port->bus;
- struct pci_dev *dev;
-
- /* Check if this is a root port event collector. */
- if (pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC || !bus)
- return;
-
- down_read(&pci_bus_sem);
- list_for_each_entry(dev, &bus->devices, bus_list)
- if (pci_is_pcie(dev)
- && pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
- pcie_pme_set_native(dev, NULL);
- up_read(&pci_bus_sem);
- }
}
/**
@@ -364,12 +347,14 @@ static int pcie_pme_probe(struct pcie_device *srv)
ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv);
if (ret) {
kfree(data);
- } else {
- pcie_pme_mark_devices(port);
- pcie_pme_interrupt_enable(port, true);
+ return ret;
}
- return ret;
+ dev_info(&port->dev, "Signaling PME with IRQ %d\n", srv->irq);
+
+ pcie_pme_mark_devices(port);
+ pcie_pme_interrupt_enable(port, true);
+ return 0;
}
static bool pcie_pme_check_wakeup(struct pci_bus *bus)
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index e9270b4026f3..9698289f105c 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -499,7 +499,6 @@ static int pcie_port_probe_service(struct device *dev)
if (status)
return status;
- dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", driver->name);
get_device(dev);
return 0;
}
@@ -524,8 +523,6 @@ static int pcie_port_remove_service(struct device *dev)
pciedev = to_pcie_device(dev);
driver = to_service_driver(dev->driver);
if (driver && driver->remove) {
- dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n",
- driver->name);
driver->remove(pciedev);
put_device(dev);
}
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 79327cc14e7d..8aa3f14bc87d 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -19,6 +19,7 @@
#include <linux/dmi.h>
#include <linux/pci-aspm.h>
+#include "../pci.h"
#include "portdrv.h"
#include "aer/aerdrv.h"
@@ -149,15 +150,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
pci_save_state(dev);
- /*
- * Prevent runtime PM if the port is advertising support for PCIe
- * hotplug. Otherwise the BIOS hotplug SMI code might not be able
- * to enumerate devices behind this port properly (the port is
- * powered down preventing all config space accesses to the
- * subordinate devices). We can't be sure for native PCIe hotplug
- * either so prevent that as well.
- */
- if (!dev->is_hotplug_bridge) {
+ if (pci_bridge_d3_possible(dev)) {
/*
* Keep the port resumed 100ms to make sure things like
* config space accesses from userspace (lspci) will not
@@ -175,7 +168,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
static void pcie_portdrv_remove(struct pci_dev *dev)
{
- if (!dev->is_hotplug_bridge) {
+ if (pci_bridge_d3_possible(dev)) {
pm_runtime_forbid(&dev->dev);
pm_runtime_get_noresume(&dev->dev);
pm_runtime_dont_use_autosuspend(&dev->dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 104c46d53121..e164b5c9f0f0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -227,7 +227,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK;
}
} else {
- res->flags |= (l & IORESOURCE_ROM_ENABLE);
+ if (l & PCI_ROM_ADDRESS_ENABLE)
+ res->flags |= IORESOURCE_ROM_ENABLE;
l64 = l & PCI_ROM_ADDRESS_MASK;
sz64 = sz & PCI_ROM_ADDRESS_MASK;
mask64 = (u32)PCI_ROM_ADDRESS_MASK;
@@ -521,18 +522,19 @@ static void pci_release_host_bridge_dev(struct device *dev)
kfree(bridge);
}
-static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
+struct pci_host_bridge *pci_alloc_host_bridge(size_t priv)
{
struct pci_host_bridge *bridge;
- bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
+ bridge = kzalloc(sizeof(*bridge) + priv, GFP_KERNEL);
if (!bridge)
return NULL;
INIT_LIST_HEAD(&bridge->windows);
- bridge->bus = b;
+
return bridge;
}
+EXPORT_SYMBOL(pci_alloc_host_bridge);
static const unsigned char pcix_bus_speed[] = {
PCI_SPEED_UNKNOWN, /* 0 */
@@ -717,6 +719,123 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
dev_set_msi_domain(&bus->dev, d);
}
+int pci_register_host_bridge(struct pci_host_bridge *bridge)
+{
+ struct device *parent = bridge->dev.parent;
+ struct resource_entry *window, *n;
+ struct pci_bus *bus, *b;
+ resource_size_t offset;
+ LIST_HEAD(resources);
+ struct resource *res;
+ char addr[64], *fmt;
+ const char *name;
+ int err;
+
+ bus = pci_alloc_bus(NULL);
+ if (!bus)
+ return -ENOMEM;
+
+ bridge->bus = bus;
+
+ /* temporarily move resources off the list */
+ list_splice_init(&bridge->windows, &resources);
+ bus->sysdata = bridge->sysdata;
+ bus->msi = bridge->msi;
+ bus->ops = bridge->ops;
+ bus->number = bus->busn_res.start = bridge->busnr;
+#ifdef CONFIG_PCI_DOMAINS_GENERIC
+ bus->domain_nr = pci_bus_find_domain_nr(bus, parent);
+#endif
+
+ b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
+ if (b) {
+ /* If we already got to this bus through a different bridge, ignore it */
+ dev_dbg(&b->dev, "bus already known\n");
+ err = -EEXIST;
+ goto free;
+ }
+
+ dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(bus),
+ bridge->busnr);
+
+ err = pcibios_root_bridge_prepare(bridge);
+ if (err)
+ goto free;
+
+ err = device_register(&bridge->dev);
+ if (err)
+ put_device(&bridge->dev);
+
+ bus->bridge = get_device(&bridge->dev);
+ device_enable_async_suspend(bus->bridge);
+ pci_set_bus_of_node(bus);
+ pci_set_bus_msi_domain(bus);
+
+ if (!parent)
+ set_dev_node(bus->bridge, pcibus_to_node(bus));
+
+ bus->dev.class = &pcibus_class;
+ bus->dev.parent = bus->bridge;
+
+ dev_set_name(&bus->dev, "%04x:%02x", pci_domain_nr(bus), bus->number);
+ name = dev_name(&bus->dev);
+
+ err = device_register(&bus->dev);
+ if (err)
+ goto unregister;
+
+ pcibios_add_bus(bus);
+
+ /* Create legacy_io and legacy_mem files for this bus */
+ pci_create_legacy_files(bus);
+
+ if (parent)
+ dev_info(parent, "PCI host bridge to bus %s\n", name);
+ else
+ pr_info("PCI host bridge to bus %s\n", name);
+
+ /* Add initial resources to the bus */
+ resource_list_for_each_entry_safe(window, n, &resources) {
+ list_move_tail(&window->node, &bridge->windows);
+ offset = window->offset;
+ res = window->res;
+
+ if (res->flags & IORESOURCE_BUS)
+ pci_bus_insert_busn_res(bus, bus->number, res->end);
+ else
+ pci_bus_add_resource(bus, res, 0);
+
+ if (offset) {
+ if (resource_type(res) == IORESOURCE_IO)
+ fmt = " (bus address [%#06llx-%#06llx])";
+ else
+ fmt = " (bus address [%#010llx-%#010llx])";
+
+ snprintf(addr, sizeof(addr), fmt,
+ (unsigned long long)(res->start - offset),
+ (unsigned long long)(res->end - offset));
+ } else
+ addr[0] = '\0';
+
+ dev_info(&bus->dev, "root bus resource %pR%s\n", res, addr);
+ }
+
+ down_write(&pci_bus_sem);
+ list_add_tail(&bus->node, &pci_root_buses);
+ up_write(&pci_bus_sem);
+
+ return 0;
+
+unregister:
+ put_device(&bridge->dev);
+ device_unregister(&bridge->dev);
+
+free:
+ kfree(bus);
+ return err;
+}
+EXPORT_SYMBOL(pci_register_host_bridge);
+
static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
struct pci_dev *bridge, int busnr)
{
@@ -1764,8 +1883,7 @@ static void pci_dma_configure(struct pci_dev *dev)
if (attr == DEV_DMA_NOT_SUPPORTED)
dev_warn(&dev->dev, "DMA not supported.\n");
else
- arch_setup_dma_ops(&dev->dev, 0, 0, NULL,
- attr == DEV_DMA_COHERENT);
+ acpi_dma_configure(&dev->dev, attr);
}
pci_put_host_bridge_device(bridge);
@@ -2156,113 +2274,43 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
{
}
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
- struct pci_ops *ops, void *sysdata, struct list_head *resources)
+static struct pci_bus *pci_create_root_bus_msi(struct device *parent,
+ int bus, struct pci_ops *ops, void *sysdata,
+ struct list_head *resources, struct msi_controller *msi)
{
int error;
struct pci_host_bridge *bridge;
- struct pci_bus *b, *b2;
- struct resource_entry *window, *n;
- struct resource *res;
- resource_size_t offset;
- char bus_addr[64];
- char *fmt;
-
- b = pci_alloc_bus(NULL);
- if (!b)
- return NULL;
- b->sysdata = sysdata;
- b->ops = ops;
- b->number = b->busn_res.start = bus;
-#ifdef CONFIG_PCI_DOMAINS_GENERIC
- b->domain_nr = pci_bus_find_domain_nr(b, parent);
-#endif
- b2 = pci_find_bus(pci_domain_nr(b), bus);
- if (b2) {
- /* If we already got to this bus through a different bridge, ignore it */
- dev_dbg(&b2->dev, "bus already known\n");
- goto err_out;
- }
-
- bridge = pci_alloc_host_bridge(b);
+ bridge = pci_alloc_host_bridge(0);
if (!bridge)
- goto err_out;
+ return NULL;
bridge->dev.parent = parent;
bridge->dev.release = pci_release_host_bridge_dev;
- dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
- error = pcibios_root_bridge_prepare(bridge);
- if (error) {
- kfree(bridge);
- goto err_out;
- }
-
- error = device_register(&bridge->dev);
- if (error) {
- put_device(&bridge->dev);
- goto err_out;
- }
- b->bridge = get_device(&bridge->dev);
- device_enable_async_suspend(b->bridge);
- pci_set_bus_of_node(b);
- pci_set_bus_msi_domain(b);
- if (!parent)
- set_dev_node(b->bridge, pcibus_to_node(b));
-
- b->dev.class = &pcibus_class;
- b->dev.parent = b->bridge;
- dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
- error = device_register(&b->dev);
- if (error)
- goto class_dev_reg_err;
+ list_splice_init(resources, &bridge->windows);
+ bridge->sysdata = sysdata;
+ bridge->busnr = bus;
+ bridge->ops = ops;
+ bridge->msi = msi;
- pcibios_add_bus(b);
-
- /* Create legacy_io and legacy_mem files for this bus */
- pci_create_legacy_files(b);
-
- if (parent)
- dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
- else
- printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
-
- /* Add initial resources to the bus */
- resource_list_for_each_entry_safe(window, n, resources) {
- list_move_tail(&window->node, &bridge->windows);
- res = window->res;
- offset = window->offset;
- if (res->flags & IORESOURCE_BUS)
- pci_bus_insert_busn_res(b, bus, res->end);
- else
- pci_bus_add_resource(b, res, 0);
- if (offset) {
- if (resource_type(res) == IORESOURCE_IO)
- fmt = " (bus address [%#06llx-%#06llx])";
- else
- fmt = " (bus address [%#010llx-%#010llx])";
- snprintf(bus_addr, sizeof(bus_addr), fmt,
- (unsigned long long) (res->start - offset),
- (unsigned long long) (res->end - offset));
- } else
- bus_addr[0] = '\0';
- dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr);
- }
+ error = pci_register_host_bridge(bridge);
+ if (error < 0)
+ goto err_out;
- down_write(&pci_bus_sem);
- list_add_tail(&b->node, &pci_root_buses);
- up_write(&pci_bus_sem);
+ return bridge->bus;
- return b;
-
-class_dev_reg_err:
- put_device(&bridge->dev);
- device_unregister(&bridge->dev);
err_out:
- kfree(b);
+ kfree(bridge);
return NULL;
}
+
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+ return pci_create_root_bus_msi(parent, bus, ops, sysdata, resources,
+ NULL);
+}
EXPORT_SYMBOL_GPL(pci_create_root_bus);
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
@@ -2343,12 +2391,10 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
break;
}
- b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
+ b = pci_create_root_bus_msi(parent, bus, ops, sysdata, resources, msi);
if (!b)
return NULL;
- b->msi = msi;
-
if (!found) {
dev_info(&b->dev,
"No busn resource found for root bus, will use [bus %02x-ff]\n",
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c232729f5b1b..9236e40ac055 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2156,7 +2156,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev)
{
if (dev->vpd) {
dev->vpd->len = 0;
- dev_warn(&dev->dev, FW_BUG "VPD access disabled\n");
+ dev_warn(&dev->dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n");
}
}
@@ -3137,8 +3137,9 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay);
+
/*
- * Some devices may pass our check in pci_intx_mask_supported if
+ * Some devices may pass our check in pci_intx_mask_supported() if
* PCI_COMMAND_INTX_DISABLE works though they actually do not properly
* support this feature.
*/
@@ -3146,53 +3147,139 @@ static void quirk_broken_intx_masking(struct pci_dev *dev)
{
dev->broken_intx_masking = 1;
}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CHELSIO, 0x0030,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
- quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x0030,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
+ quirk_broken_intx_masking);
+
/*
* Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10)
* Subsystem: Realtek RTL8169/8110 Family PCI Gigabit Ethernet NIC
*
* RTL8110SC - Fails under PCI device assignment using DisINTx masking.
*/
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID,
- quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, 0x8169,
+ quirk_broken_intx_masking);
/*
* Intel i40e (XL710/X710) 10/20/40GbE NICs all have broken INTx masking,
* DisINTx can be set but the interrupt status bit is non-functional.
*/
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1572,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1574,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1580,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1581,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1583,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1584,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1585,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1586,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1587,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1588,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1589,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d0,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d1,
- quirk_broken_intx_masking);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x37d2,
- quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1572,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1574,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1580,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1581,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1583,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1584,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1585,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1586,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1587,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1588,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1589,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1,
+ quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2,
+ quirk_broken_intx_masking);
+
+static u16 mellanox_broken_intx_devs[] = {
+ PCI_DEVICE_ID_MELLANOX_HERMON_SDR,
+ PCI_DEVICE_ID_MELLANOX_HERMON_DDR,
+ PCI_DEVICE_ID_MELLANOX_HERMON_QDR,
+ PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2,
+ PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2,
+ PCI_DEVICE_ID_MELLANOX_HERMON_EN,
+ PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX_EN,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX2,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX3,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO,
+};
+
+#define CONNECTX_4_CURR_MAX_MINOR 99
+#define CONNECTX_4_INTX_SUPPORT_MINOR 14
+
+/*
+ * Check ConnectX-4/LX FW version to see if it supports legacy interrupts.
+ * If so, don't mark it as broken.
+ * FW minor > 99 means older FW version format and no INTx masking support.
+ * FW minor < 14 means new FW version format and no INTx masking support.
+ */
+static void mellanox_check_broken_intx_masking(struct pci_dev *pdev)
+{
+ __be32 __iomem *fw_ver;
+ u16 fw_major;
+ u16 fw_minor;
+ u16 fw_subminor;
+ u32 fw_maj_min;
+ u32 fw_sub_min;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mellanox_broken_intx_devs); i++) {
+ if (pdev->device == mellanox_broken_intx_devs[i]) {
+ pdev->broken_intx_masking = 1;
+ return;
+ }
+ }
+
+ /* Getting here means Connect-IB cards and up. Connect-IB has no INTx
+ * support so shouldn't be checked further
+ */
+ if (pdev->device == PCI_DEVICE_ID_MELLANOX_CONNECTIB)
+ return;
+
+ if (pdev->device != PCI_DEVICE_ID_MELLANOX_CONNECTX4 &&
+ pdev->device != PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX)
+ return;
+
+ /* For ConnectX-4 and ConnectX-4LX, need to check FW support */
+ if (pci_enable_device_mem(pdev)) {
+ dev_warn(&pdev->dev, "Can't enable device memory\n");
+ return;
+ }
+
+ fw_ver = ioremap(pci_resource_start(pdev, 0), 4);
+ if (!fw_ver) {
+ dev_warn(&pdev->dev, "Can't map ConnectX-4 initialization segment\n");
+ goto out;
+ }
+
+ /* Reading from resource space should be 32b aligned */
+ fw_maj_min = ioread32be(fw_ver);
+ fw_sub_min = ioread32be(fw_ver + 1);
+ fw_major = fw_maj_min & 0xffff;
+ fw_minor = fw_maj_min >> 16;
+ fw_subminor = fw_sub_min & 0xffff;
+ if (fw_minor > CONNECTX_4_CURR_MAX_MINOR ||
+ fw_minor < CONNECTX_4_INTX_SUPPORT_MINOR) {
+ dev_warn(&pdev->dev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n",
+ fw_major, fw_minor, fw_subminor, pdev->device ==
+ PCI_DEVICE_ID_MELLANOX_CONNECTX4 ? 12 : 14);
+ pdev->broken_intx_masking = 1;
+ }
+
+ iounmap(fw_ver);
+
+out:
+ pci_disable_device(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID,
+ mellanox_check_broken_intx_masking);
static void quirk_no_bus_reset(struct pci_dev *dev)
{
@@ -3255,6 +3342,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
quirk_thunderbolt_hotplug_msi);
+static void quirk_chelsio_extend_vpd(struct pci_dev *dev)
+{
+ pci_set_vpd_size(dev, 8192);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd);
+
#ifdef CONFIG_ACPI
/*
* Apple: Shutdown Cactus Ridge Thunderbolt controller.
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index f9357e09e9b3..73a03d382590 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -40,7 +40,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
list_del(&dev->bus_list);
up_write(&pci_bus_sem);
- pci_bridge_d3_device_removed(dev);
+ pci_bridge_d3_update(dev);
pci_free_resources(dev);
put_device(&dev->dev);
}
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 06663d391b39..b6edb187d160 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -35,6 +35,11 @@ int pci_enable_rom(struct pci_dev *pdev)
if (res->flags & IORESOURCE_ROM_SHADOW)
return 0;
+ /*
+ * Ideally pci_update_resource() would update the ROM BAR address,
+ * and we would only set the enable bit here. But apparently some
+ * devices have buggy ROM BARs that read as zero when disabled.
+ */
pcibios_resource_to_bus(pdev->bus, &region, res);
pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
rom_addr &= ~PCI_ROM_ADDRESS_MASK;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 9526e341988b..4bc589ee78d0 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -25,21 +25,18 @@
#include <linux/slab.h>
#include "pci.h"
-
-void pci_update_resource(struct pci_dev *dev, int resno)
+static void pci_std_update_resource(struct pci_dev *dev, int resno)
{
struct pci_bus_region region;
bool disable;
u16 cmd;
u32 new, check, mask;
int reg;
- enum pci_bar_type type;
struct resource *res = dev->resource + resno;
- if (dev->is_virtfn) {
- dev_warn(&dev->dev, "can't update VF BAR%d\n", resno);
+ /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
+ if (dev->is_virtfn)
return;
- }
/*
* Ignore resources for unimplemented BARs and unused resource slots
@@ -60,21 +57,34 @@ void pci_update_resource(struct pci_dev *dev, int resno)
return;
pcibios_resource_to_bus(dev->bus, &region, res);
+ new = region.start;
- new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
- if (res->flags & IORESOURCE_IO)
+ if (res->flags & IORESOURCE_IO) {
mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
- else
+ new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
+ } else if (resno == PCI_ROM_RESOURCE) {
+ mask = (u32)PCI_ROM_ADDRESS_MASK;
+ } else {
mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
+ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
+ }
- reg = pci_resource_bar(dev, resno, &type);
- if (!reg)
- return;
- if (type != pci_bar_unknown) {
+ if (resno < PCI_ROM_RESOURCE) {
+ reg = PCI_BASE_ADDRESS_0 + 4 * resno;
+ } else if (resno == PCI_ROM_RESOURCE) {
+
+ /*
+ * Apparently some Matrox devices have ROM BARs that read
+ * as zero when disabled, so don't update ROM BARs unless
+ * they're enabled. See https://lkml.org/lkml/2005/8/30/138.
+ */
if (!(res->flags & IORESOURCE_ROM_ENABLE))
return;
+
+ reg = dev->rom_base_reg;
new |= PCI_ROM_ADDRESS_ENABLE;
- }
+ } else
+ return;
/*
* We can't update a 64-bit BAR atomically, so when possible,
@@ -110,6 +120,16 @@ void pci_update_resource(struct pci_dev *dev, int resno)
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
+void pci_update_resource(struct pci_dev *dev, int resno)
+{
+ if (resno <= PCI_ROM_RESOURCE)
+ pci_std_update_resource(dev, resno);
+#ifdef CONFIG_PCI_IOV
+ else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
+ pci_iov_update_resource(dev, resno);
+#endif
+}
+
int pci_claim_resource(struct pci_dev *dev, int resource)
{
struct resource *res = &dev->resource[resource];
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 1bb38d0493eb..85d009112864 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -75,12 +75,6 @@ enum bcm2835_pinconf_param {
BCM2835_PINCONF_PARAM_PULL,
};
-enum bcm2835_pinconf_pull {
- BCM2835_PINCONFIG_PULL_NONE,
- BCM2835_PINCONFIG_PULL_DOWN,
- BCM2835_PINCONFIG_PULL_UP,
-};
-
#define BCM2835_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_))
#define BCM2835_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16)
#define BCM2835_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b8a21d7b25d4..185376901d9c 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1027,4 +1027,15 @@ config INTEL_TELEMETRY
used to get various SoC events and parameters
directly via debugfs files. Various tools may use
this interface for SoC state monitoring.
+
+config MLX_CPLD_PLATFORM
+ tristate "Mellanox platform hotplug driver support"
+ default n
+ depends on MLX_PLATFORM
+ select HWMON
+ select I2C
+ ---help---
+ This driver handles hot-plug events for the power suppliers, power
+ cables and fans on the wide range Mellanox IB and Ethernet systems.
+
endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 2efa86d2a1a7..1f06b6339cf7 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
intel_telemetry_pltdrv.o \
intel_telemetry_debugfs.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
+obj-$(CONFIG_MLX_CPLD_PLATFORM) += mlxcpld-hotplug.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 79d64ea00bfb..a66192f692e3 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -355,6 +355,32 @@ static const struct dmi_system_id acer_blacklist[] __initconst = {
{}
};
+static const struct dmi_system_id amw0_whitelist[] __initconst = {
+ {
+ .ident = "Acer",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ },
+ },
+ {
+ .ident = "Gateway",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gateway"),
+ },
+ },
+ {
+ .ident = "Packard Bell",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"),
+ },
+ },
+ {}
+};
+
+/*
+ * This quirk table is only for Acer/Gateway/Packard Bell family
+ * that those machines are supported by acer-wmi driver.
+ */
static const struct dmi_system_id acer_quirks[] __initconst = {
{
.callback = dmi_matched,
@@ -464,6 +490,17 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
},
.driver_data = &quirk_acer_travelmate_2490,
},
+ {}
+};
+
+/*
+ * This quirk list is for those non-acer machines that have AMW0_GUID1
+ * but supported by acer-wmi in past days. Keeping this quirk list here
+ * is only for backward compatible. Please do not add new machine to
+ * here anymore. Those non-acer machines should be supported by
+ * appropriate wmi drivers.
+ */
+static const struct dmi_system_id non_acer_quirks[] __initconst = {
{
.callback = dmi_matched,
.ident = "Fujitsu Siemens Amilo Li 1718",
@@ -598,6 +635,7 @@ static void __init find_quirks(void)
{
if (!force_series) {
dmi_check_system(acer_quirks);
+ dmi_check_system(non_acer_quirks);
} else if (force_series == 2490) {
quirks = &quirk_acer_travelmate_2490;
}
@@ -2108,6 +2146,24 @@ static int __init acer_wmi_init(void)
find_quirks();
/*
+ * The AMW0_GUID1 wmi is not only found on Acer family but also other
+ * machines like Lenovo, Fujitsu and Medion. In the past days,
+ * acer-wmi driver handled those non-Acer machines by quirks list.
+ * But actually acer-wmi driver was loaded on any machines that have
+ * AMW0_GUID1. This behavior is strange because those machines should
+ * be supported by appropriate wmi drivers. e.g. fujitsu-laptop,
+ * ideapad-laptop. So, here checks the machine that has AMW0_GUID1
+ * should be in Acer/Gateway/Packard Bell white list, or it's already
+ * in the past quirk list.
+ */
+ if (wmi_has_guid(AMW0_GUID1) &&
+ !dmi_check_system(amw0_whitelist) &&
+ quirks == &quirk_unknown) {
+ pr_err("Unsupported machine has AMW0_GUID1, unable to load\n");
+ return -ENODEV;
+ }
+
+ /*
* Detect which ACPI-WMI interface we're using.
*/
if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 26e4cbc34db8..5be4783e40d4 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -116,8 +116,13 @@ static struct quirk_entry quirk_asus_ux303ub = {
.wmi_backlight_native = true,
};
+static struct quirk_entry quirk_asus_x550lb = {
+ .xusb2pr = 0x01D9,
+};
+
static int dmi_matched(const struct dmi_system_id *dmi)
{
+ pr_info("Identified laptop model '%s'\n", dmi->ident);
quirks = dmi->driver_data;
return 1;
}
@@ -175,6 +180,15 @@ static const struct dmi_system_id asus_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X45U",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X45U"),
+ },
+ .driver_data = &quirk_asus_wapf4,
+ },
+ {
+ .callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. X456UA",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
@@ -398,6 +412,15 @@ static const struct dmi_system_id asus_quirks[] = {
},
.driver_data = &quirk_asus_ux303ub,
},
+ {
+ .callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. X550LB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"),
+ },
+ .driver_data = &quirk_asus_x550lb,
+ },
{},
};
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index ce6ca31a2d09..43cb680adbb4 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -156,6 +156,9 @@ MODULE_LICENSE("GPL");
#define ASUS_FAN_CTRL_MANUAL 1
#define ASUS_FAN_CTRL_AUTO 2
+#define USB_INTEL_XUSB2PR 0xD0
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
+
struct bios_args {
u32 arg0;
u32 arg1;
@@ -1080,6 +1083,29 @@ exit:
return result;
}
+static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
+{
+ struct pci_dev *xhci_pdev;
+ u32 orig_ports_available;
+ u32 ports_available = asus->driver->quirks->xusb2pr;
+
+ xhci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI,
+ NULL);
+
+ if (!xhci_pdev)
+ return;
+
+ pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
+ &orig_ports_available);
+
+ pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
+ cpu_to_le32(ports_available));
+
+ pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
+ orig_ports_available, ports_available);
+}
+
/*
* Hwmon device
*/
@@ -2087,6 +2113,9 @@ static int asus_wmi_add(struct platform_device *pdev)
if (asus->driver->quirks->wmi_backlight_native)
acpi_video_set_dmi_backlight_type(acpi_backlight_native);
+ if (asus->driver->quirks->xusb2pr)
+ asus_wmi_set_xusb2pr(asus);
+
if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
err = asus_wmi_backlight_init(asus);
if (err && err != -ENODEV)
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 0e19014e9f54..fdff626c3b51 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -53,6 +53,7 @@ struct quirk_entry {
* and let the ACPI interrupt to send out the key event.
*/
int no_display_toggle;
+ u32 xusb2pr;
bool (*i8042_filter)(unsigned char data, unsigned char str,
struct serio *serio);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 2c2f02b2e08a..14392a01ab36 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -1904,38 +1904,40 @@ static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)
return 0;
}
-static void kbd_led_level_set(struct led_classdev *led_cdev,
- enum led_brightness value)
+static int kbd_led_level_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
{
struct kbd_state state;
struct kbd_state new_state;
u16 num;
+ int ret;
if (kbd_get_max_level()) {
- if (kbd_get_state(&state))
- return;
+ ret = kbd_get_state(&state);
+ if (ret)
+ return ret;
new_state = state;
- if (kbd_set_level(&new_state, value))
- return;
- kbd_set_state_safe(&new_state, &state);
- return;
+ ret = kbd_set_level(&new_state, value);
+ if (ret)
+ return ret;
+ return kbd_set_state_safe(&new_state, &state);
}
if (kbd_get_valid_token_counts()) {
for (num = kbd_token_bits; num != 0 && value > 0; --value)
num &= num - 1; /* clear the first bit set */
if (num == 0)
- return;
- kbd_set_token_bit(ffs(num) - 1);
- return;
+ return 0;
+ return kbd_set_token_bit(ffs(num) - 1);
}
pr_warn("Keyboard brightness level control not supported\n");
+ return -ENXIO;
}
static struct led_classdev kbd_led = {
.name = "dell::kbd_backlight",
- .brightness_set = kbd_led_level_set,
+ .brightness_set_blocking = kbd_led_level_set,
.brightness_get = kbd_led_level_get,
.groups = kbd_led_groups,
};
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index da2fe18162e1..75e637047d36 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -114,7 +114,7 @@ static const struct key_entry dell_wmi_keymap_type_0000[] __initconst = {
{ KE_IGNORE, 0xe00e, { KEY_RESERVED } },
/* Wifi Catcher */
- { KE_KEY, 0xe011, { KEY_PROG2 } },
+ { KE_KEY, 0xe011, { KEY_WLAN } },
/* Ambient light sensor toggle */
{ KE_IGNORE, 0xe013, { KEY_RESERVED } },
@@ -274,6 +274,16 @@ static const struct key_entry dell_wmi_keymap_type_0010[] __initconst = {
/* Stealth mode toggle */
{ KE_IGNORE, 0x155, { KEY_RESERVED } },
+
+ /* Rugged magnetic dock attach/detach events */
+ { KE_IGNORE, 0x156, { KEY_RESERVED } },
+ { KE_IGNORE, 0x157, { KEY_RESERVED } },
+
+ /* Rugged programmable (P1/P2/P3 keys) */
+ { KE_KEY, 0x850, { KEY_PROG1 } },
+ { KE_KEY, 0x851, { KEY_PROG2 } },
+ { KE_KEY, 0x852, { KEY_PROG3 } },
+
};
/*
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
index 12dbb5063376..cb3ab2b212b1 100644
--- a/drivers/platform/x86/intel-hid.c
+++ b/drivers/platform/x86/intel-hid.c
@@ -69,7 +69,7 @@ static int intel_hid_set_enable(struct device *device, int enable)
arg0.integer.value = enable;
status = acpi_evaluate_object(ACPI_HANDLE(device), "HDSM", &args, NULL);
- if (!ACPI_SUCCESS(status)) {
+ if (ACPI_FAILURE(status)) {
dev_warn(device, "failed to %sable hotkeys\n",
enable ? "en" : "dis");
return -EIO;
@@ -148,7 +148,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
}
status = acpi_evaluate_integer(handle, "HDEM", NULL, &ev_index);
- if (!ACPI_SUCCESS(status)) {
+ if (ACPI_FAILURE(status)) {
dev_warn(&device->dev, "failed to get event index\n");
return;
}
@@ -167,7 +167,7 @@ static int intel_hid_probe(struct platform_device *device)
int err;
status = acpi_evaluate_integer(handle, "HDMM", NULL, &mode);
- if (!ACPI_SUCCESS(status)) {
+ if (ACPI_FAILURE(status)) {
dev_warn(&device->dev, "failed to read mode\n");
return -ENODEV;
}
diff --git a/drivers/platform/x86/intel-smartconnect.c b/drivers/platform/x86/intel-smartconnect.c
index 04cf5dffdfd9..bbe4c06c769f 100644
--- a/drivers/platform/x86/intel-smartconnect.c
+++ b/drivers/platform/x86/intel-smartconnect.c
@@ -29,7 +29,7 @@ static int smartconnect_acpi_init(struct acpi_device *acpi)
acpi_status status;
status = acpi_evaluate_integer(acpi->handle, "GAOS", NULL, &value);
- if (!ACPI_SUCCESS(status))
+ if (ACPI_FAILURE(status))
return -EINVAL;
if (value & 0x1) {
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index 78080763df51..554e82ebe83c 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -49,34 +49,19 @@ static int intel_vbtn_input_setup(struct platform_device *device)
struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
int ret;
- priv->input_dev = input_allocate_device();
+ priv->input_dev = devm_input_allocate_device(&device->dev);
if (!priv->input_dev)
return -ENOMEM;
ret = sparse_keymap_setup(priv->input_dev, intel_vbtn_keymap, NULL);
if (ret)
- goto err_free_device;
+ return ret;
priv->input_dev->dev.parent = &device->dev;
priv->input_dev->name = "Intel Virtual Button driver";
priv->input_dev->id.bustype = BUS_HOST;
- ret = input_register_device(priv->input_dev);
- if (ret)
- goto err_free_device;
-
- return 0;
-
-err_free_device:
- input_free_device(priv->input_dev);
- return ret;
-}
-
-static void intel_vbtn_input_destroy(struct platform_device *device)
-{
- struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
-
- input_unregister_device(priv->input_dev);
+ return input_register_device(priv->input_dev);
}
static void notify_handler(acpi_handle handle, u32 event, void *context)
@@ -97,7 +82,7 @@ static int intel_vbtn_probe(struct platform_device *device)
int err;
status = acpi_evaluate_object(handle, "VBDL", NULL, NULL);
- if (!ACPI_SUCCESS(status)) {
+ if (ACPI_FAILURE(status)) {
dev_warn(&device->dev, "failed to read Intel Virtual Button driver\n");
return -ENODEV;
}
@@ -117,24 +102,16 @@ static int intel_vbtn_probe(struct platform_device *device)
ACPI_DEVICE_NOTIFY,
notify_handler,
device);
- if (ACPI_FAILURE(status)) {
- err = -EBUSY;
- goto err_remove_input;
- }
+ if (ACPI_FAILURE(status))
+ return -EBUSY;
return 0;
-
-err_remove_input:
- intel_vbtn_input_destroy(device);
-
- return err;
}
static int intel_vbtn_remove(struct platform_device *device)
{
acpi_handle handle = ACPI_HANDLE(&device->dev);
- intel_vbtn_input_destroy(device);
acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
/*
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
index 9f713b832ba3..0df3c9d37509 100644
--- a/drivers/platform/x86/intel_mid_thermal.c
+++ b/drivers/platform/x86/intel_mid_thermal.c
@@ -415,6 +415,7 @@ static struct thermal_device_info *initialize_sensor(int index)
return td_info;
}
+#ifdef CONFIG_PM_SLEEP
/**
* mid_thermal_resume - resume routine
* @dev: device structure
@@ -442,6 +443,7 @@ static int mid_thermal_suspend(struct device *dev)
*/
return configure_adc(0);
}
+#endif
static SIMPLE_DEV_PM_OPS(mid_thermal_pm,
mid_thermal_suspend, mid_thermal_resume);
diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index e8b1b836ca2d..b130b8c9b9d7 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -19,10 +19,12 @@
*/
#include <linux/debugfs.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/pci.h>
+#include <linux/uaccess.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
@@ -32,16 +34,106 @@
static struct pmc_dev pmc;
+static const struct pmc_bit_map spt_pll_map[] = {
+ {"MIPI PLL", SPT_PMC_BIT_MPHY_CMN_LANE0},
+ {"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1},
+ {"DMIPCIE3 PLL", SPT_PMC_BIT_MPHY_CMN_LANE2},
+ {"SATA PLL", SPT_PMC_BIT_MPHY_CMN_LANE3},
+ {},
+};
+
+static const struct pmc_bit_map spt_mphy_map[] = {
+ {"MPHY CORE LANE 0", SPT_PMC_BIT_MPHY_LANE0},
+ {"MPHY CORE LANE 1", SPT_PMC_BIT_MPHY_LANE1},
+ {"MPHY CORE LANE 2", SPT_PMC_BIT_MPHY_LANE2},
+ {"MPHY CORE LANE 3", SPT_PMC_BIT_MPHY_LANE3},
+ {"MPHY CORE LANE 4", SPT_PMC_BIT_MPHY_LANE4},
+ {"MPHY CORE LANE 5", SPT_PMC_BIT_MPHY_LANE5},
+ {"MPHY CORE LANE 6", SPT_PMC_BIT_MPHY_LANE6},
+ {"MPHY CORE LANE 7", SPT_PMC_BIT_MPHY_LANE7},
+ {"MPHY CORE LANE 8", SPT_PMC_BIT_MPHY_LANE8},
+ {"MPHY CORE LANE 9", SPT_PMC_BIT_MPHY_LANE9},
+ {"MPHY CORE LANE 10", SPT_PMC_BIT_MPHY_LANE10},
+ {"MPHY CORE LANE 11", SPT_PMC_BIT_MPHY_LANE11},
+ {"MPHY CORE LANE 12", SPT_PMC_BIT_MPHY_LANE12},
+ {"MPHY CORE LANE 13", SPT_PMC_BIT_MPHY_LANE13},
+ {"MPHY CORE LANE 14", SPT_PMC_BIT_MPHY_LANE14},
+ {"MPHY CORE LANE 15", SPT_PMC_BIT_MPHY_LANE15},
+ {},
+};
+
+static const struct pmc_bit_map spt_pfear_map[] = {
+ {"PMC", SPT_PMC_BIT_PMC},
+ {"OPI-DMI", SPT_PMC_BIT_OPI},
+ {"SPI / eSPI", SPT_PMC_BIT_SPI},
+ {"XHCI", SPT_PMC_BIT_XHCI},
+ {"SPA", SPT_PMC_BIT_SPA},
+ {"SPB", SPT_PMC_BIT_SPB},
+ {"SPC", SPT_PMC_BIT_SPC},
+ {"GBE", SPT_PMC_BIT_GBE},
+ {"SATA", SPT_PMC_BIT_SATA},
+ {"HDA-PGD0", SPT_PMC_BIT_HDA_PGD0},
+ {"HDA-PGD1", SPT_PMC_BIT_HDA_PGD1},
+ {"HDA-PGD2", SPT_PMC_BIT_HDA_PGD2},
+ {"HDA-PGD3", SPT_PMC_BIT_HDA_PGD3},
+ {"RSVD", SPT_PMC_BIT_RSVD_0B},
+ {"LPSS", SPT_PMC_BIT_LPSS},
+ {"LPC", SPT_PMC_BIT_LPC},
+ {"SMB", SPT_PMC_BIT_SMB},
+ {"ISH", SPT_PMC_BIT_ISH},
+ {"P2SB", SPT_PMC_BIT_P2SB},
+ {"DFX", SPT_PMC_BIT_DFX},
+ {"SCC", SPT_PMC_BIT_SCC},
+ {"RSVD", SPT_PMC_BIT_RSVD_0C},
+ {"FUSE", SPT_PMC_BIT_FUSE},
+ {"CAMERA", SPT_PMC_BIT_CAMREA},
+ {"RSVD", SPT_PMC_BIT_RSVD_0D},
+ {"USB3-OTG", SPT_PMC_BIT_USB3_OTG},
+ {"EXI", SPT_PMC_BIT_EXI},
+ {"CSE", SPT_PMC_BIT_CSE},
+ {"CSME_KVM", SPT_PMC_BIT_CSME_KVM},
+ {"CSME_PMT", SPT_PMC_BIT_CSME_PMT},
+ {"CSME_CLINK", SPT_PMC_BIT_CSME_CLINK},
+ {"CSME_PTIO", SPT_PMC_BIT_CSME_PTIO},
+ {"CSME_USBR", SPT_PMC_BIT_CSME_USBR},
+ {"CSME_SUSRAM", SPT_PMC_BIT_CSME_SUSRAM},
+ {"CSME_SMT", SPT_PMC_BIT_CSME_SMT},
+ {"RSVD", SPT_PMC_BIT_RSVD_1A},
+ {"CSME_SMS2", SPT_PMC_BIT_CSME_SMS2},
+ {"CSME_SMS1", SPT_PMC_BIT_CSME_SMS1},
+ {"CSME_RTC", SPT_PMC_BIT_CSME_RTC},
+ {"CSME_PSF", SPT_PMC_BIT_CSME_PSF},
+ {},
+};
+
+static const struct pmc_reg_map spt_reg_map = {
+ .pfear_sts = spt_pfear_map,
+ .mphy_sts = spt_mphy_map,
+ .pll_sts = spt_pll_map,
+};
+
static const struct pci_device_id pmc_pci_ids[] = {
- { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID), (kernel_ulong_t)NULL },
+ { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID),
+ (kernel_ulong_t)&spt_reg_map },
{ 0, },
};
+static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
+{
+ return readb(pmcdev->regbase + offset);
+}
+
static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset)
{
return readl(pmcdev->regbase + reg_offset);
}
+static inline void pmc_core_reg_write(struct pmc_dev *pmcdev, int
+ reg_offset, u32 val)
+{
+ writel(val, pmcdev->regbase + reg_offset);
+}
+
static inline u32 pmc_core_adjust_slp_s0_step(u32 value)
{
return value * SPT_PMC_SLP_S0_RES_COUNTER_STEP;
@@ -90,6 +182,245 @@ static int pmc_core_dev_state_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(pmc_core_dev_state, pmc_core_dev_state_get, NULL, "%llu\n");
+static int pmc_core_check_read_lock_bit(void)
+{
+ struct pmc_dev *pmcdev = &pmc;
+ u32 value;
+
+ value = pmc_core_reg_read(pmcdev, SPT_PMC_PM_CFG_OFFSET);
+ return test_bit(SPT_PMC_READ_DISABLE_BIT,
+ (unsigned long *)&value);
+}
+
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+static void pmc_core_display_map(struct seq_file *s, int index,
+ u8 pf_reg, const struct pmc_bit_map *pf_map)
+{
+ seq_printf(s, "PCH IP: %-2d - %-32s\tState: %s\n",
+ index, pf_map[index].name,
+ pf_map[index].bit_mask & pf_reg ? "Off" : "On");
+}
+
+static int pmc_core_ppfear_sts_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+ const struct pmc_bit_map *map = pmcdev->map->pfear_sts;
+ u8 pf_regs[NUM_ENTRIES];
+ int index, iter;
+
+ iter = SPT_PMC_XRAM_PPFEAR0A;
+
+ for (index = 0; index < NUM_ENTRIES; index++, iter++)
+ pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
+
+ for (index = 0; map[index].name; index++)
+ pmc_core_display_map(s, index, pf_regs[index / 8], map);
+
+ return 0;
+}
+
+static int pmc_core_ppfear_sts_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pmc_core_ppfear_sts_show, inode->i_private);
+}
+
+static const struct file_operations pmc_core_ppfear_ops = {
+ .open = pmc_core_ppfear_sts_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* This function should return link status, 0 means ready */
+static int pmc_core_mtpmc_link_status(void)
+{
+ struct pmc_dev *pmcdev = &pmc;
+ u32 value;
+
+ value = pmc_core_reg_read(pmcdev, SPT_PMC_PM_STS_OFFSET);
+ return test_bit(SPT_PMC_MSG_FULL_STS_BIT,
+ (unsigned long *)&value);
+}
+
+static int pmc_core_send_msg(u32 *addr_xram)
+{
+ struct pmc_dev *pmcdev = &pmc;
+ u32 dest;
+ int timeout;
+
+ for (timeout = NUM_RETRIES; timeout > 0; timeout--) {
+ if (pmc_core_mtpmc_link_status() == 0)
+ break;
+ msleep(5);
+ }
+
+ if (timeout <= 0 && pmc_core_mtpmc_link_status())
+ return -EBUSY;
+
+ dest = (*addr_xram & MTPMC_MASK) | (1U << 1);
+ pmc_core_reg_write(pmcdev, SPT_PMC_MTPMC_OFFSET, dest);
+ return 0;
+}
+
+static int pmc_core_mphy_pg_sts_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+ const struct pmc_bit_map *map = pmcdev->map->mphy_sts;
+ u32 mphy_core_reg_low, mphy_core_reg_high;
+ u32 val_low, val_high;
+ int index, err = 0;
+
+ if (pmcdev->pmc_xram_read_bit) {
+ seq_puts(s, "Access denied: please disable PMC_READ_DISABLE setting in BIOS.");
+ return 0;
+ }
+
+ mphy_core_reg_low = (SPT_PMC_MPHY_CORE_STS_0 << 16);
+ mphy_core_reg_high = (SPT_PMC_MPHY_CORE_STS_1 << 16);
+
+ mutex_lock(&pmcdev->lock);
+
+ if (pmc_core_send_msg(&mphy_core_reg_low) != 0) {
+ err = -EBUSY;
+ goto out_unlock;
+ }
+
+ msleep(10);
+ val_low = pmc_core_reg_read(pmcdev, SPT_PMC_MFPMC_OFFSET);
+
+ if (pmc_core_send_msg(&mphy_core_reg_high) != 0) {
+ err = -EBUSY;
+ goto out_unlock;
+ }
+
+ msleep(10);
+ val_high = pmc_core_reg_read(pmcdev, SPT_PMC_MFPMC_OFFSET);
+
+ for (index = 0; map[index].name && index < 8; index++) {
+ seq_printf(s, "%-32s\tState: %s\n",
+ map[index].name,
+ map[index].bit_mask & val_low ? "Not power gated" :
+ "Power gated");
+ }
+
+ for (index = 8; map[index].name; index++) {
+ seq_printf(s, "%-32s\tState: %s\n",
+ map[index].name,
+ map[index].bit_mask & val_high ? "Not power gated" :
+ "Power gated");
+ }
+
+out_unlock:
+ mutex_unlock(&pmcdev->lock);
+ return err;
+}
+
+static int pmc_core_mphy_pg_sts_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pmc_core_mphy_pg_sts_show, inode->i_private);
+}
+
+static const struct file_operations pmc_core_mphy_pg_ops = {
+ .open = pmc_core_mphy_pg_sts_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int pmc_core_pll_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+ const struct pmc_bit_map *map = pmcdev->map->pll_sts;
+ u32 mphy_common_reg, val;
+ int index, err = 0;
+
+ if (pmcdev->pmc_xram_read_bit) {
+ seq_puts(s, "Access denied: please disable PMC_READ_DISABLE setting in BIOS.");
+ return 0;
+ }
+
+ mphy_common_reg = (SPT_PMC_MPHY_COM_STS_0 << 16);
+ mutex_lock(&pmcdev->lock);
+
+ if (pmc_core_send_msg(&mphy_common_reg) != 0) {
+ err = -EBUSY;
+ goto out_unlock;
+ }
+
+ /* Observed PMC HW response latency for MTPMC-MFPMC is ~10 ms */
+ msleep(10);
+ val = pmc_core_reg_read(pmcdev, SPT_PMC_MFPMC_OFFSET);
+
+ for (index = 0; map[index].name ; index++) {
+ seq_printf(s, "%-32s\tState: %s\n",
+ map[index].name,
+ map[index].bit_mask & val ? "Active" : "Idle");
+ }
+
+out_unlock:
+ mutex_unlock(&pmcdev->lock);
+ return err;
+}
+
+static int pmc_core_pll_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pmc_core_pll_show, inode->i_private);
+}
+
+static const struct file_operations pmc_core_pll_ops = {
+ .open = pmc_core_pll_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static ssize_t pmc_core_ltr_ignore_write(struct file *file, const char __user
+*userbuf, size_t count, loff_t *ppos)
+{
+ struct pmc_dev *pmcdev = &pmc;
+ u32 val, buf_size, fd;
+ int err = 0;
+
+ buf_size = count < 64 ? count : 64;
+ mutex_lock(&pmcdev->lock);
+
+ if (kstrtou32_from_user(userbuf, buf_size, 10, &val)) {
+ err = -EFAULT;
+ goto out_unlock;
+ }
+
+ if (val > NUM_IP_IGN_ALLOWED) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ fd = pmc_core_reg_read(pmcdev, SPT_PMC_LTR_IGNORE_OFFSET);
+ fd |= (1U << val);
+ pmc_core_reg_write(pmcdev, SPT_PMC_LTR_IGNORE_OFFSET, fd);
+
+out_unlock:
+ mutex_unlock(&pmcdev->lock);
+ return err == 0 ? count : err;
+}
+
+static int pmc_core_ltr_ignore_show(struct seq_file *s, void *unused)
+{
+ return 0;
+}
+
+static int pmc_core_ltr_ignore_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pmc_core_ltr_ignore_show, inode->i_private);
+}
+
+static const struct file_operations pmc_core_ltr_ignore_ops = {
+ .open = pmc_core_ltr_ignore_open,
+ .read = seq_read,
+ .write = pmc_core_ltr_ignore_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
{
debugfs_remove_recursive(pmcdev->dbgfs_dir);
@@ -106,20 +437,59 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
pmcdev->dbgfs_dir = dir;
file = debugfs_create_file("slp_s0_residency_usec", S_IFREG | S_IRUGO,
dir, pmcdev, &pmc_core_dev_state);
+ if (!file)
+ goto err;
- if (!file) {
- pmc_core_dbgfs_unregister(pmcdev);
- return -ENODEV;
- }
+ file = debugfs_create_file("pch_ip_power_gating_status",
+ S_IFREG | S_IRUGO, dir, pmcdev,
+ &pmc_core_ppfear_ops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("mphy_core_lanes_power_gating_status",
+ S_IFREG | S_IRUGO, dir, pmcdev,
+ &pmc_core_mphy_pg_ops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("pll_status",
+ S_IFREG | S_IRUGO, dir, pmcdev,
+ &pmc_core_pll_ops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("ltr_ignore",
+ S_IFREG | S_IRUGO, dir, pmcdev,
+ &pmc_core_ltr_ignore_ops);
+
+ if (!file)
+ goto err;
return 0;
+err:
+ pmc_core_dbgfs_unregister(pmcdev);
+ return -ENODEV;
}
+#else
+static inline int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
+{
+ return 0;
+}
+
+static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
static const struct x86_cpu_id intel_pmc_core_ids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_MOBILE, X86_FEATURE_MWAIT,
(kernel_ulong_t)NULL},
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_DESKTOP, X86_FEATURE_MWAIT,
(kernel_ulong_t)NULL},
+ { X86_VENDOR_INTEL, 6, INTEL_FAM6_KABYLAKE_MOBILE, X86_FEATURE_MWAIT,
+ (kernel_ulong_t)NULL},
+ { X86_VENDOR_INTEL, 6, INTEL_FAM6_KABYLAKE_DESKTOP, X86_FEATURE_MWAIT,
+ (kernel_ulong_t)NULL},
{}
};
@@ -128,6 +498,7 @@ static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
struct device *ptr_dev = &dev->dev;
struct pmc_dev *pmcdev = &pmc;
const struct x86_cpu_id *cpu_id;
+ const struct pmc_reg_map *map = (struct pmc_reg_map *)id->driver_data;
int err;
cpu_id = x86_match_cpu(intel_pmc_core_ids);
@@ -149,6 +520,7 @@ static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
dev_dbg(&dev->dev, "PMC Core: failed to read PCI config space.\n");
return err;
}
+ pmcdev->base_addr &= PMC_BASE_ADDR_MASK;
dev_dbg(&dev->dev, "PMC Core: PWRMBASE is %#x\n", pmcdev->base_addr);
pmcdev->regbase = devm_ioremap_nocache(ptr_dev,
@@ -159,6 +531,10 @@ static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENOMEM;
}
+ mutex_init(&pmcdev->lock);
+ pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
+ pmcdev->map = map;
+
err = pmc_core_dbgfs_register(pmcdev);
if (err < 0)
dev_warn(&dev->dev, "PMC Core: debugfs register failed.\n");
diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h
index e3f671f4d122..5a48e7728479 100644
--- a/drivers/platform/x86/intel_pmc_core.h
+++ b/drivers/platform/x86/intel_pmc_core.h
@@ -26,8 +26,111 @@
#define SPT_PMC_BASE_ADDR_OFFSET 0x48
#define SPT_PMC_SLP_S0_RES_COUNTER_OFFSET 0x13c
-#define SPT_PMC_MMIO_REG_LEN 0x100
+#define SPT_PMC_PM_CFG_OFFSET 0x18
+#define SPT_PMC_PM_STS_OFFSET 0x1c
+#define SPT_PMC_MTPMC_OFFSET 0x20
+#define SPT_PMC_MFPMC_OFFSET 0x38
+#define SPT_PMC_LTR_IGNORE_OFFSET 0x30C
+#define SPT_PMC_MPHY_CORE_STS_0 0x1143
+#define SPT_PMC_MPHY_CORE_STS_1 0x1142
+#define SPT_PMC_MPHY_COM_STS_0 0x1155
+#define SPT_PMC_MMIO_REG_LEN 0x1000
#define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64
+#define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1)
+#define MTPMC_MASK 0xffff0000
+#define NUM_ENTRIES 5
+#define SPT_PMC_READ_DISABLE_BIT 0x16
+#define SPT_PMC_MSG_FULL_STS_BIT 0x18
+#define NUM_RETRIES 100
+#define NUM_IP_IGN_ALLOWED 17
+
+/* Sunrise Point: PGD PFET Enable Ack Status Registers */
+enum ppfear_regs {
+ SPT_PMC_XRAM_PPFEAR0A = 0x590,
+ SPT_PMC_XRAM_PPFEAR0B,
+ SPT_PMC_XRAM_PPFEAR0C,
+ SPT_PMC_XRAM_PPFEAR0D,
+ SPT_PMC_XRAM_PPFEAR1A,
+};
+
+#define SPT_PMC_BIT_PMC BIT(0)
+#define SPT_PMC_BIT_OPI BIT(1)
+#define SPT_PMC_BIT_SPI BIT(2)
+#define SPT_PMC_BIT_XHCI BIT(3)
+#define SPT_PMC_BIT_SPA BIT(4)
+#define SPT_PMC_BIT_SPB BIT(5)
+#define SPT_PMC_BIT_SPC BIT(6)
+#define SPT_PMC_BIT_GBE BIT(7)
+
+#define SPT_PMC_BIT_SATA BIT(0)
+#define SPT_PMC_BIT_HDA_PGD0 BIT(1)
+#define SPT_PMC_BIT_HDA_PGD1 BIT(2)
+#define SPT_PMC_BIT_HDA_PGD2 BIT(3)
+#define SPT_PMC_BIT_HDA_PGD3 BIT(4)
+#define SPT_PMC_BIT_RSVD_0B BIT(5)
+#define SPT_PMC_BIT_LPSS BIT(6)
+#define SPT_PMC_BIT_LPC BIT(7)
+
+#define SPT_PMC_BIT_SMB BIT(0)
+#define SPT_PMC_BIT_ISH BIT(1)
+#define SPT_PMC_BIT_P2SB BIT(2)
+#define SPT_PMC_BIT_DFX BIT(3)
+#define SPT_PMC_BIT_SCC BIT(4)
+#define SPT_PMC_BIT_RSVD_0C BIT(5)
+#define SPT_PMC_BIT_FUSE BIT(6)
+#define SPT_PMC_BIT_CAMREA BIT(7)
+
+#define SPT_PMC_BIT_RSVD_0D BIT(0)
+#define SPT_PMC_BIT_USB3_OTG BIT(1)
+#define SPT_PMC_BIT_EXI BIT(2)
+#define SPT_PMC_BIT_CSE BIT(3)
+#define SPT_PMC_BIT_CSME_KVM BIT(4)
+#define SPT_PMC_BIT_CSME_PMT BIT(5)
+#define SPT_PMC_BIT_CSME_CLINK BIT(6)
+#define SPT_PMC_BIT_CSME_PTIO BIT(7)
+
+#define SPT_PMC_BIT_CSME_USBR BIT(0)
+#define SPT_PMC_BIT_CSME_SUSRAM BIT(1)
+#define SPT_PMC_BIT_CSME_SMT BIT(2)
+#define SPT_PMC_BIT_RSVD_1A BIT(3)
+#define SPT_PMC_BIT_CSME_SMS2 BIT(4)
+#define SPT_PMC_BIT_CSME_SMS1 BIT(5)
+#define SPT_PMC_BIT_CSME_RTC BIT(6)
+#define SPT_PMC_BIT_CSME_PSF BIT(7)
+
+#define SPT_PMC_BIT_MPHY_LANE0 BIT(0)
+#define SPT_PMC_BIT_MPHY_LANE1 BIT(1)
+#define SPT_PMC_BIT_MPHY_LANE2 BIT(2)
+#define SPT_PMC_BIT_MPHY_LANE3 BIT(3)
+#define SPT_PMC_BIT_MPHY_LANE4 BIT(4)
+#define SPT_PMC_BIT_MPHY_LANE5 BIT(5)
+#define SPT_PMC_BIT_MPHY_LANE6 BIT(6)
+#define SPT_PMC_BIT_MPHY_LANE7 BIT(7)
+
+#define SPT_PMC_BIT_MPHY_LANE8 BIT(0)
+#define SPT_PMC_BIT_MPHY_LANE9 BIT(1)
+#define SPT_PMC_BIT_MPHY_LANE10 BIT(2)
+#define SPT_PMC_BIT_MPHY_LANE11 BIT(3)
+#define SPT_PMC_BIT_MPHY_LANE12 BIT(4)
+#define SPT_PMC_BIT_MPHY_LANE13 BIT(5)
+#define SPT_PMC_BIT_MPHY_LANE14 BIT(6)
+#define SPT_PMC_BIT_MPHY_LANE15 BIT(7)
+
+#define SPT_PMC_BIT_MPHY_CMN_LANE0 BIT(0)
+#define SPT_PMC_BIT_MPHY_CMN_LANE1 BIT(1)
+#define SPT_PMC_BIT_MPHY_CMN_LANE2 BIT(2)
+#define SPT_PMC_BIT_MPHY_CMN_LANE3 BIT(3)
+
+struct pmc_bit_map {
+ const char *name;
+ u32 bit_mask;
+};
+
+struct pmc_reg_map {
+ const struct pmc_bit_map *pfear_sts;
+ const struct pmc_bit_map *mphy_sts;
+ const struct pmc_bit_map *pll_sts;
+};
/**
* struct pmc_dev - pmc device structure
@@ -43,8 +146,13 @@
struct pmc_dev {
u32 base_addr;
void __iomem *regbase;
+ const struct pmc_reg_map *map;
+#if IS_ENABLED(CONFIG_DEBUG_FS)
struct dentry *dbgfs_dir;
+#endif /* CONFIG_DEBUG_FS */
bool has_slp_s0_res;
+ int pmc_xram_read_bit;
+ struct mutex lock; /* generic mutex lock for PMC Core */
};
#endif /* PMC_CORE_H */
diff --git a/drivers/platform/x86/mlxcpld-hotplug.c b/drivers/platform/x86/mlxcpld-hotplug.c
new file mode 100644
index 000000000000..aff3686b3b37
--- /dev/null
+++ b/drivers/platform/x86/mlxcpld-hotplug.c
@@ -0,0 +1,515 @@
+/*
+ * drivers/platform/x86/mlxcpld-hotplug.c
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_data/mlxcpld-hotplug.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+/* Offset of event and mask registers from status register */
+#define MLXCPLD_HOTPLUG_EVENT_OFF 1
+#define MLXCPLD_HOTPLUG_MASK_OFF 2
+#define MLXCPLD_HOTPLUG_AGGR_MASK_OFF 1
+
+#define MLXCPLD_HOTPLUG_ATTRS_NUM 8
+
+/**
+ * enum mlxcpld_hotplug_attr_type - sysfs attributes for hotplug events:
+ * @MLXCPLD_HOTPLUG_ATTR_TYPE_PSU: power supply unit attribute;
+ * @MLXCPLD_HOTPLUG_ATTR_TYPE_PWR: power cable attribute;
+ * @MLXCPLD_HOTPLUG_ATTR_TYPE_FAN: FAN drawer attribute;
+ */
+enum mlxcpld_hotplug_attr_type {
+ MLXCPLD_HOTPLUG_ATTR_TYPE_PSU,
+ MLXCPLD_HOTPLUG_ATTR_TYPE_PWR,
+ MLXCPLD_HOTPLUG_ATTR_TYPE_FAN,
+};
+
+/**
+ * struct mlxcpld_hotplug_priv_data - platform private data:
+ * @irq: platform interrupt number;
+ * @pdev: platform device;
+ * @plat: platform data;
+ * @hwmon: hwmon device;
+ * @mlxcpld_hotplug_attr: sysfs attributes array;
+ * @mlxcpld_hotplug_dev_attr: sysfs sensor device attribute array;
+ * @group: sysfs attribute group;
+ * @groups: list of sysfs attribute group for hwmon registration;
+ * @dwork: delayed work template;
+ * @lock: spin lock;
+ * @aggr_cache: last value of aggregation register status;
+ * @psu_cache: last value of PSU register status;
+ * @pwr_cache: last value of power register status;
+ * @fan_cache: last value of FAN register status;
+ */
+struct mlxcpld_hotplug_priv_data {
+ int irq;
+ struct platform_device *pdev;
+ struct mlxcpld_hotplug_platform_data *plat;
+ struct device *hwmon;
+ struct attribute *mlxcpld_hotplug_attr[MLXCPLD_HOTPLUG_ATTRS_NUM + 1];
+ struct sensor_device_attribute_2
+ mlxcpld_hotplug_dev_attr[MLXCPLD_HOTPLUG_ATTRS_NUM];
+ struct attribute_group group;
+ const struct attribute_group *groups[2];
+ struct delayed_work dwork;
+ spinlock_t lock;
+ u8 aggr_cache;
+ u8 psu_cache;
+ u8 pwr_cache;
+ u8 fan_cache;
+};
+
+static ssize_t mlxcpld_hotplug_attr_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev);
+ int index = to_sensor_dev_attr_2(attr)->index;
+ int nr = to_sensor_dev_attr_2(attr)->nr;
+ u8 reg_val = 0;
+
+ switch (nr) {
+ case MLXCPLD_HOTPLUG_ATTR_TYPE_PSU:
+ /* Bit = 0 : PSU is present. */
+ reg_val = !!!(inb(priv->plat->psu_reg_offset) & BIT(index));
+ break;
+
+ case MLXCPLD_HOTPLUG_ATTR_TYPE_PWR:
+ /* Bit = 1 : power cable is attached. */
+ reg_val = !!(inb(priv->plat->pwr_reg_offset) & BIT(index %
+ priv->plat->pwr_count));
+ break;
+
+ case MLXCPLD_HOTPLUG_ATTR_TYPE_FAN:
+ /* Bit = 0 : FAN is present. */
+ reg_val = !!!(inb(priv->plat->fan_reg_offset) & BIT(index %
+ priv->plat->fan_count));
+ break;
+ }
+
+ return sprintf(buf, "%u\n", reg_val);
+}
+
+#define PRIV_ATTR(i) priv->mlxcpld_hotplug_attr[i]
+#define PRIV_DEV_ATTR(i) priv->mlxcpld_hotplug_dev_attr[i]
+static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv)
+{
+ int num_attrs = priv->plat->psu_count + priv->plat->pwr_count +
+ priv->plat->fan_count;
+ int i;
+
+ priv->group.attrs = devm_kzalloc(&priv->pdev->dev, num_attrs *
+ sizeof(struct attribute *),
+ GFP_KERNEL);
+ if (!priv->group.attrs)
+ return -ENOMEM;
+
+ for (i = 0; i < num_attrs; i++) {
+ PRIV_ATTR(i) = &PRIV_DEV_ATTR(i).dev_attr.attr;
+
+ if (i < priv->plat->psu_count) {
+ PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
+ GFP_KERNEL, "psu%u", i + 1);
+ PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PSU;
+ } else if (i < priv->plat->psu_count + priv->plat->pwr_count) {
+ PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
+ GFP_KERNEL, "pwr%u", i %
+ priv->plat->pwr_count + 1);
+ PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PWR;
+ } else {
+ PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
+ GFP_KERNEL, "fan%u", i %
+ priv->plat->fan_count + 1);
+ PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_FAN;
+ }
+
+ if (!PRIV_ATTR(i)->name) {
+ dev_err(&priv->pdev->dev, "Memory allocation failed for sysfs attribute %d.\n",
+ i + 1);
+ return -ENOMEM;
+ }
+
+ PRIV_DEV_ATTR(i).dev_attr.attr.name = PRIV_ATTR(i)->name;
+ PRIV_DEV_ATTR(i).dev_attr.attr.mode = S_IRUGO;
+ PRIV_DEV_ATTR(i).dev_attr.show = mlxcpld_hotplug_attr_show;
+ PRIV_DEV_ATTR(i).index = i;
+ sysfs_attr_init(&PRIV_DEV_ATTR(i).dev_attr.attr);
+ }
+
+ priv->group.attrs = priv->mlxcpld_hotplug_attr;
+ priv->groups[0] = &priv->group;
+ priv->groups[1] = NULL;
+
+ return 0;
+}
+
+static int mlxcpld_hotplug_device_create(struct device *dev,
+ struct mlxcpld_hotplug_device *item)
+{
+ item->adapter = i2c_get_adapter(item->bus);
+ if (!item->adapter) {
+ dev_err(dev, "Failed to get adapter for bus %d\n",
+ item->bus);
+ return -EFAULT;
+ }
+
+ item->client = i2c_new_device(item->adapter, &item->brdinfo);
+ if (!item->client) {
+ dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
+ item->brdinfo.type, item->bus, item->brdinfo.addr);
+ i2c_put_adapter(item->adapter);
+ item->adapter = NULL;
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void mlxcpld_hotplug_device_destroy(struct mlxcpld_hotplug_device *item)
+{
+ if (item->client) {
+ i2c_unregister_device(item->client);
+ item->client = NULL;
+ }
+
+ if (item->adapter) {
+ i2c_put_adapter(item->adapter);
+ item->adapter = NULL;
+ }
+}
+
+static inline void
+mlxcpld_hotplug_work_helper(struct device *dev,
+ struct mlxcpld_hotplug_device *item, u8 is_inverse,
+ u16 offset, u8 mask, u8 *cache)
+{
+ u8 val, asserted;
+ int bit;
+
+ /* Mask event. */
+ outb(0, offset + MLXCPLD_HOTPLUG_MASK_OFF);
+ /* Read status. */
+ val = inb(offset) & mask;
+ asserted = *cache ^ val;
+ *cache = val;
+
+ /*
+ * Validate if item related to received signal type is valid.
+ * It should never happen, excepted the situation when some
+ * piece of hardware is broken. In such situation just produce
+ * error message and return. Caller must continue to handle the
+ * signals from other devices if any.
+ */
+ if (unlikely(!item)) {
+ dev_err(dev, "False signal is received: register at offset 0x%02x, mask 0x%02x.\n",
+ offset, mask);
+ return;
+ }
+
+ for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
+ if (val & BIT(bit)) {
+ if (is_inverse)
+ mlxcpld_hotplug_device_destroy(item + bit);
+ else
+ mlxcpld_hotplug_device_create(dev, item + bit);
+ } else {
+ if (is_inverse)
+ mlxcpld_hotplug_device_create(dev, item + bit);
+ else
+ mlxcpld_hotplug_device_destroy(item + bit);
+ }
+ }
+
+ /* Acknowledge event. */
+ outb(0, offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+ /* Unmask event. */
+ outb(mask, offset + MLXCPLD_HOTPLUG_MASK_OFF);
+}
+
+/*
+ * mlxcpld_hotplug_work_handler - performs traversing of CPLD interrupt
+ * registers according to the below hierarchy schema:
+ *
+ * Aggregation registers (status/mask)
+ * PSU registers: *---*
+ * *-----------------* | |
+ * |status/event/mask|----->| * |
+ * *-----------------* | |
+ * Power registers: | |
+ * *-----------------* | |
+ * |status/event/mask|----->| * |---> CPU
+ * *-----------------* | |
+ * FAN registers:
+ * *-----------------* | |
+ * |status/event/mask|----->| * |
+ * *-----------------* | |
+ * *---*
+ * In case some system changed are detected: FAN in/out, PSU in/out, power
+ * cable attached/detached, relevant device is created or destroyed.
+ */
+static void mlxcpld_hotplug_work_handler(struct work_struct *work)
+{
+ struct mlxcpld_hotplug_priv_data *priv = container_of(work,
+ struct mlxcpld_hotplug_priv_data, dwork.work);
+ u8 val, aggr_asserted;
+ unsigned long flags;
+
+ /* Mask aggregation event. */
+ outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
+ /* Read aggregation status. */
+ val = inb(priv->plat->top_aggr_offset) & priv->plat->top_aggr_mask;
+ aggr_asserted = priv->aggr_cache ^ val;
+ priv->aggr_cache = val;
+
+ /* Handle PSU configuration changes. */
+ if (aggr_asserted & priv->plat->top_aggr_psu_mask)
+ mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->psu,
+ 1, priv->plat->psu_reg_offset,
+ priv->plat->psu_mask,
+ &priv->psu_cache);
+
+ /* Handle power cable configuration changes. */
+ if (aggr_asserted & priv->plat->top_aggr_pwr_mask)
+ mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->pwr,
+ 0, priv->plat->pwr_reg_offset,
+ priv->plat->pwr_mask,
+ &priv->pwr_cache);
+
+ /* Handle FAN configuration changes. */
+ if (aggr_asserted & priv->plat->top_aggr_fan_mask)
+ mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->fan,
+ 1, priv->plat->fan_reg_offset,
+ priv->plat->fan_mask,
+ &priv->fan_cache);
+
+ if (aggr_asserted) {
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /*
+ * It is possible, that some signals have been inserted, while
+ * interrupt has been masked by mlxcpld_hotplug_work_handler.
+ * In this case such signals will be missed. In order to handle
+ * these signals delayed work is canceled and work task
+ * re-scheduled for immediate execution. It allows to handle
+ * missed signals, if any. In other case work handler just
+ * validates that no new signals have been received during
+ * masking.
+ */
+ cancel_delayed_work(&priv->dwork);
+ schedule_delayed_work(&priv->dwork, 0);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return;
+ }
+
+ /* Unmask aggregation event (no need acknowledge). */
+ outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
+ MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
+}
+
+static void mlxcpld_hotplug_set_irq(struct mlxcpld_hotplug_priv_data *priv)
+{
+ /* Clear psu presense event. */
+ outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+ /* Set psu initial status as mask and unmask psu event. */
+ priv->psu_cache = priv->plat->psu_mask;
+ outb(priv->plat->psu_mask, priv->plat->psu_reg_offset +
+ MLXCPLD_HOTPLUG_MASK_OFF);
+
+ /* Clear power cable event. */
+ outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+ /* Keep power initial status as zero and unmask power event. */
+ outb(priv->plat->pwr_mask, priv->plat->pwr_reg_offset +
+ MLXCPLD_HOTPLUG_MASK_OFF);
+
+ /* Clear fan presense event. */
+ outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+ /* Set fan initial status as mask and unmask fan event. */
+ priv->fan_cache = priv->plat->fan_mask;
+ outb(priv->plat->fan_mask, priv->plat->fan_reg_offset +
+ MLXCPLD_HOTPLUG_MASK_OFF);
+
+ /* Keep aggregation initial status as zero and unmask events. */
+ outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
+ MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
+
+ /* Invoke work handler for initializing hot plug devices setting. */
+ mlxcpld_hotplug_work_handler(&priv->dwork.work);
+
+ enable_irq(priv->irq);
+}
+
+static void mlxcpld_hotplug_unset_irq(struct mlxcpld_hotplug_priv_data *priv)
+{
+ int i;
+
+ disable_irq(priv->irq);
+ cancel_delayed_work_sync(&priv->dwork);
+
+ /* Mask aggregation event. */
+ outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
+
+ /* Mask psu presense event. */
+ outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
+ /* Clear psu presense event. */
+ outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+
+ /* Mask power cable event. */
+ outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
+ /* Clear power cable event. */
+ outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+
+ /* Mask fan presense event. */
+ outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
+ /* Clear fan presense event. */
+ outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
+
+ /* Remove all the attached devices. */
+ for (i = 0; i < priv->plat->psu_count; i++)
+ mlxcpld_hotplug_device_destroy(priv->plat->psu + i);
+
+ for (i = 0; i < priv->plat->pwr_count; i++)
+ mlxcpld_hotplug_device_destroy(priv->plat->pwr + i);
+
+ for (i = 0; i < priv->plat->fan_count; i++)
+ mlxcpld_hotplug_device_destroy(priv->plat->fan + i);
+}
+
+static irqreturn_t mlxcpld_hotplug_irq_handler(int irq, void *dev)
+{
+ struct mlxcpld_hotplug_priv_data *priv =
+ (struct mlxcpld_hotplug_priv_data *)dev;
+
+ /* Schedule work task for immediate execution.*/
+ schedule_delayed_work(&priv->dwork, 0);
+
+ return IRQ_HANDLED;
+}
+
+static int mlxcpld_hotplug_probe(struct platform_device *pdev)
+{
+ struct mlxcpld_hotplug_platform_data *pdata;
+ struct mlxcpld_hotplug_priv_data *priv;
+ int err;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Failed to get platform data.\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->pdev = pdev;
+ priv->plat = pdata;
+
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq < 0) {
+ dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
+ priv->irq);
+ return priv->irq;
+ }
+
+ err = devm_request_irq(&pdev->dev, priv->irq,
+ mlxcpld_hotplug_irq_handler, 0, pdev->name,
+ priv);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
+ return err;
+ }
+ disable_irq(priv->irq);
+
+ INIT_DELAYED_WORK(&priv->dwork, mlxcpld_hotplug_work_handler);
+ spin_lock_init(&priv->lock);
+
+ err = mlxcpld_hotplug_attr_init(priv);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to allocate attributes: %d\n", err);
+ return err;
+ }
+
+ priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+ "mlxcpld_hotplug", priv, priv->groups);
+ if (IS_ERR(priv->hwmon)) {
+ dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
+ PTR_ERR(priv->hwmon));
+ return PTR_ERR(priv->hwmon);
+ }
+
+ platform_set_drvdata(pdev, priv);
+
+ /* Perform initial interrupts setup. */
+ mlxcpld_hotplug_set_irq(priv);
+
+ return 0;
+}
+
+static int mlxcpld_hotplug_remove(struct platform_device *pdev)
+{
+ struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev);
+
+ /* Clean interrupts setup. */
+ mlxcpld_hotplug_unset_irq(priv);
+
+ return 0;
+}
+
+static struct platform_driver mlxcpld_hotplug_driver = {
+ .driver = {
+ .name = "mlxcpld-hotplug",
+ },
+ .probe = mlxcpld_hotplug_probe,
+ .remove = mlxcpld_hotplug_remove,
+};
+
+module_platform_driver(mlxcpld_hotplug_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox CPLD hotplug platform driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:mlxcpld-hotplug");
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index 3f870972247c..59b8eb626dcc 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -458,7 +458,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY,
NULL, &result);
- if (!ACPI_SUCCESS(rc)) {
+ if (ACPI_FAILURE(rc)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"error getting hotkey status\n"));
return;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index b65ce7519411..aa65a857a6b1 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -128,6 +128,7 @@ enum {
/* ACPI HIDs */
#define TPACPI_ACPI_IBM_HKEY_HID "IBM0068"
#define TPACPI_ACPI_LENOVO_HKEY_HID "LEN0068"
+#define TPACPI_ACPI_LENOVO_HKEY_V2_HID "LEN0268"
#define TPACPI_ACPI_EC_HID "PNP0C09"
/* Input IDs */
@@ -190,6 +191,9 @@ enum tpacpi_hkey_event_t {
TP_HKEY_EV_LID_OPEN = 0x5002, /* laptop lid opened */
TP_HKEY_EV_TABLET_TABLET = 0x5009, /* tablet swivel up */
TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a, /* tablet swivel down */
+ TP_HKEY_EV_TABLET_CHANGED = 0x60c0, /* X1 Yoga (2016):
+ * enter/leave tablet mode
+ */
TP_HKEY_EV_PEN_INSERTED = 0x500b, /* tablet pen inserted */
TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */
TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */
@@ -302,7 +306,12 @@ static struct {
u32 hotkey:1;
u32 hotkey_mask:1;
u32 hotkey_wlsw:1;
- u32 hotkey_tablet:1;
+ enum {
+ TP_HOTKEY_TABLET_NONE = 0,
+ TP_HOTKEY_TABLET_USES_MHKG,
+ /* X1 Yoga 2016, seen on BIOS N1FET44W */
+ TP_HOTKEY_TABLET_USES_CMMD,
+ } hotkey_tablet;
u32 kbdlight:1;
u32 light:1;
u32 light_status:1;
@@ -2059,6 +2068,8 @@ static void hotkey_poll_setup(const bool may_warn);
/* HKEY.MHKG() return bits */
#define TP_HOTKEY_TABLET_MASK (1 << 3)
+/* ThinkPad X1 Yoga (2016) */
+#define TP_EC_CMMD_TABLET_MODE 0x6
static int hotkey_get_wlsw(void)
{
@@ -2083,10 +2094,23 @@ static int hotkey_get_tablet_mode(int *status)
{
int s;
- if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
- return -EIO;
+ switch (tp_features.hotkey_tablet) {
+ case TP_HOTKEY_TABLET_USES_MHKG:
+ if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
+ return -EIO;
+
+ *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);
+ break;
+ case TP_HOTKEY_TABLET_USES_CMMD:
+ if (!acpi_evalf(ec_handle, &s, "CMMD", "d"))
+ return -EIO;
+
+ *status = (s == TP_EC_CMMD_TABLET_MODE);
+ break;
+ default:
+ break;
+ }
- *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);
return 0;
}
@@ -3117,6 +3141,37 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
typedef u16 tpacpi_keymap_entry_t;
typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
+static int hotkey_init_tablet_mode(void)
+{
+ int in_tablet_mode = 0, res;
+ char *type = NULL;
+
+ if (acpi_evalf(hkey_handle, &res, "MHKG", "qd")) {
+ /* For X41t, X60t, X61t Tablets... */
+ tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_MHKG;
+ in_tablet_mode = !!(res & TP_HOTKEY_TABLET_MASK);
+ type = "MHKG";
+ } else if (acpi_evalf(ec_handle, &res, "CMMD", "qd")) {
+ /* For X1 Yoga (2016) */
+ tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_CMMD;
+ in_tablet_mode = res == TP_EC_CMMD_TABLET_MODE;
+ type = "CMMD";
+ }
+
+ if (!tp_features.hotkey_tablet)
+ return 0;
+
+ pr_info("Tablet mode switch found (type: %s), currently in %s mode\n",
+ type, in_tablet_mode ? "tablet" : "laptop");
+
+ res = add_to_attr_set(hotkey_dev_attributes,
+ &dev_attr_hotkey_tablet_mode.attr);
+ if (res)
+ return -1;
+
+ return in_tablet_mode;
+}
+
static int __init hotkey_init(struct ibm_init_struct *iibm)
{
/* Requirements for changing the default keymaps:
@@ -3464,21 +3519,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
res = add_to_attr_set(hotkey_dev_attributes,
&dev_attr_hotkey_radio_sw.attr);
- /* For X41t, X60t, X61t Tablets... */
- if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
- tp_features.hotkey_tablet = 1;
- tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
- pr_info("possible tablet mode switch found; "
- "ThinkPad in %s mode\n",
- (tabletsw_state) ? "tablet" : "laptop");
- res = add_to_attr_set(hotkey_dev_attributes,
- &dev_attr_hotkey_tablet_mode.attr);
- }
+ res = hotkey_init_tablet_mode();
+ if (res < 0)
+ goto err_exit;
- if (!res)
- res = register_attr_set_with_sysfs(
- hotkey_dev_attributes,
- &tpacpi_pdev->dev.kobj);
+ tabletsw_state = res;
+
+ res = register_attr_set_with_sysfs(hotkey_dev_attributes,
+ &tpacpi_pdev->dev.kobj);
if (res)
goto err_exit;
@@ -3899,6 +3947,12 @@ static bool hotkey_notify_6xxx(const u32 hkey,
*ignore_acpi_ev = true;
return true;
+ case TP_HKEY_EV_TABLET_CHANGED:
+ tpacpi_input_send_tabletsw();
+ hotkey_tablet_mode_notify_change();
+ *send_acpi_ev = false;
+ break;
+
default:
pr_warn("unknown possible thermal alarm or keyboard event received\n");
known = false;
@@ -4143,6 +4197,7 @@ errexit:
static const struct acpi_device_id ibm_htk_device_ids[] = {
{TPACPI_ACPI_IBM_HKEY_HID, 0},
{TPACPI_ACPI_LENOVO_HKEY_HID, 0},
+ {TPACPI_ACPI_LENOVO_HKEY_V2_HID, 0},
{"", 0},
};
@@ -7716,7 +7771,7 @@ static struct ibm_struct volume_driver_data = {
#define alsa_card NULL
-static void inline volume_alsa_notify_change(void)
+static inline void volume_alsa_notify_change(void)
{
}
@@ -9018,7 +9073,7 @@ static int mute_led_on_off(struct tp_led_table *t, bool state)
acpi_handle temp;
int output;
- if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) {
+ if (ACPI_FAILURE(acpi_get_handle(hkey_handle, t->name, &temp))) {
pr_warn("Thinkpad ACPI has no %s interface.\n", t->name);
return -EIO;
}
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index bf0128899c09..f92dd41b0395 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -175,6 +175,15 @@ config PWM_FSL_FTM
To compile this driver as a module, choose M here: the module
will be called pwm-fsl-ftm.
+config PWM_HIBVT
+ tristate "HiSilicon BVT PWM support"
+ depends on ARCH_HISI || COMPILE_TEST
+ help
+ Generic PWM framework driver for HiSilicon BVT SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-hibvt.
+
config PWM_IMG
tristate "Imagination Technologies PWM driver"
depends on HAS_IOMEM
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 1194c54efcc2..a48bdb517792 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PWM_CRC) += pwm-crc.o
obj-$(CONFIG_PWM_CROS_EC) += pwm-cros-ec.o
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
+obj-$(CONFIG_PWM_HIBVT) += pwm-hibvt.o
obj-$(CONFIG_PWM_IMG) += pwm-img.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
diff --git a/drivers/pwm/pwm-hibvt.c b/drivers/pwm/pwm-hibvt.c
new file mode 100644
index 000000000000..d0e8f8542626
--- /dev/null
+++ b/drivers/pwm/pwm-hibvt.c
@@ -0,0 +1,271 @@
+/*
+ * PWM Controller Driver for HiSilicon BVT SoCs
+ *
+ * Copyright (c) 2016 HiSilicon Technologies Co., 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/reset.h>
+
+#define PWM_CFG0_ADDR(x) (((x) * 0x20) + 0x0)
+#define PWM_CFG1_ADDR(x) (((x) * 0x20) + 0x4)
+#define PWM_CFG2_ADDR(x) (((x) * 0x20) + 0x8)
+#define PWM_CTRL_ADDR(x) (((x) * 0x20) + 0xC)
+
+#define PWM_ENABLE_SHIFT 0
+#define PWM_ENABLE_MASK BIT(0)
+
+#define PWM_POLARITY_SHIFT 1
+#define PWM_POLARITY_MASK BIT(1)
+
+#define PWM_KEEP_SHIFT 2
+#define PWM_KEEP_MASK BIT(2)
+
+#define PWM_PERIOD_MASK GENMASK(31, 0)
+#define PWM_DUTY_MASK GENMASK(31, 0)
+
+struct hibvt_pwm_chip {
+ struct pwm_chip chip;
+ struct clk *clk;
+ void __iomem *base;
+ struct reset_control *rstc;
+};
+
+struct hibvt_pwm_soc {
+ u32 num_pwms;
+};
+
+static const struct hibvt_pwm_soc pwm_soc[2] = {
+ { .num_pwms = 4 },
+ { .num_pwms = 8 },
+};
+
+static inline struct hibvt_pwm_chip *to_hibvt_pwm_chip(struct pwm_chip *chip)
+{
+ return container_of(chip, struct hibvt_pwm_chip, chip);
+}
+
+static void hibvt_pwm_set_bits(void __iomem *base, u32 offset,
+ u32 mask, u32 data)
+{
+ void __iomem *address = base + offset;
+ u32 value;
+
+ value = readl(address);
+ value &= ~mask;
+ value |= (data & mask);
+ writel(value, address);
+}
+
+static void hibvt_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
+
+ hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
+ PWM_ENABLE_MASK, 0x1);
+}
+
+static void hibvt_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
+
+ hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
+ PWM_ENABLE_MASK, 0x0);
+}
+
+static void hibvt_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_cycle_ns, int period_ns)
+{
+ struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
+ u32 freq, period, duty;
+
+ freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000);
+
+ period = div_u64(freq * period_ns, 1000);
+ duty = div_u64(period * duty_cycle_ns, period_ns);
+
+ hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG0_ADDR(pwm->hwpwm),
+ PWM_PERIOD_MASK, period);
+
+ hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG1_ADDR(pwm->hwpwm),
+ PWM_DUTY_MASK, duty);
+}
+
+static void hibvt_pwm_set_polarity(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
+
+ if (polarity == PWM_POLARITY_INVERSED)
+ hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
+ PWM_POLARITY_MASK, (0x1 << PWM_POLARITY_SHIFT));
+ else
+ hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
+ PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT));
+}
+
+static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
+ void __iomem *base;
+ u32 freq, value;
+
+ freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000);
+ base = hi_pwm_chip->base;
+
+ value = readl(base + PWM_CFG0_ADDR(pwm->hwpwm));
+ state->period = div_u64(value * 1000, freq);
+
+ value = readl(base + PWM_CFG1_ADDR(pwm->hwpwm));
+ state->duty_cycle = div_u64(value * 1000, freq);
+
+ value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
+ state->enabled = (PWM_ENABLE_MASK & value);
+}
+
+static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ if (state->polarity != pwm->state.polarity)
+ hibvt_pwm_set_polarity(chip, pwm, state->polarity);
+
+ if (state->period != pwm->state.period ||
+ state->duty_cycle != pwm->state.duty_cycle)
+ hibvt_pwm_config(chip, pwm, state->duty_cycle, state->period);
+
+ if (state->enabled != pwm->state.enabled) {
+ if (state->enabled)
+ hibvt_pwm_enable(chip, pwm);
+ else
+ hibvt_pwm_disable(chip, pwm);
+ }
+
+ return 0;
+}
+
+static struct pwm_ops hibvt_pwm_ops = {
+ .get_state = hibvt_pwm_get_state,
+ .apply = hibvt_pwm_apply,
+
+ .owner = THIS_MODULE,
+};
+
+static int hibvt_pwm_probe(struct platform_device *pdev)
+{
+ const struct hibvt_pwm_soc *soc =
+ of_device_get_match_data(&pdev->dev);
+ struct hibvt_pwm_chip *pwm_chip;
+ struct resource *res;
+ int ret;
+ int i;
+
+ pwm_chip = devm_kzalloc(&pdev->dev, sizeof(*pwm_chip), GFP_KERNEL);
+ if (pwm_chip == NULL)
+ return -ENOMEM;
+
+ pwm_chip->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(pwm_chip->clk)) {
+ dev_err(&pdev->dev, "getting clock failed with %ld\n",
+ PTR_ERR(pwm_chip->clk));
+ return PTR_ERR(pwm_chip->clk);
+ }
+
+ pwm_chip->chip.ops = &hibvt_pwm_ops;
+ pwm_chip->chip.dev = &pdev->dev;
+ pwm_chip->chip.base = -1;
+ pwm_chip->chip.npwm = soc->num_pwms;
+ pwm_chip->chip.of_xlate = of_pwm_xlate_with_flags;
+ pwm_chip->chip.of_pwm_n_cells = 3;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pwm_chip->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pwm_chip->base))
+ return PTR_ERR(pwm_chip->base);
+
+ ret = clk_prepare_enable(pwm_chip->clk);
+ if (ret < 0)
+ return ret;
+
+ pwm_chip->rstc = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(pwm_chip->rstc)) {
+ clk_disable_unprepare(pwm_chip->clk);
+ return PTR_ERR(pwm_chip->rstc);
+ }
+
+ reset_control_assert(pwm_chip->rstc);
+ msleep(30);
+ reset_control_deassert(pwm_chip->rstc);
+
+ ret = pwmchip_add(&pwm_chip->chip);
+ if (ret < 0) {
+ clk_disable_unprepare(pwm_chip->clk);
+ return ret;
+ }
+
+ for (i = 0; i < pwm_chip->chip.npwm; i++) {
+ hibvt_pwm_set_bits(pwm_chip->base, PWM_CTRL_ADDR(i),
+ PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT));
+ }
+
+ platform_set_drvdata(pdev, pwm_chip);
+
+ return 0;
+}
+
+static int hibvt_pwm_remove(struct platform_device *pdev)
+{
+ struct hibvt_pwm_chip *pwm_chip;
+
+ pwm_chip = platform_get_drvdata(pdev);
+
+ reset_control_assert(pwm_chip->rstc);
+ msleep(30);
+ reset_control_deassert(pwm_chip->rstc);
+
+ clk_disable_unprepare(pwm_chip->clk);
+
+ return pwmchip_remove(&pwm_chip->chip);
+}
+
+static const struct of_device_id hibvt_pwm_of_match[] = {
+ { .compatible = "hisilicon,hi3516cv300-pwm", .data = &pwm_soc[0] },
+ { .compatible = "hisilicon,hi3519v100-pwm", .data = &pwm_soc[1] },
+ { }
+};
+MODULE_DEVICE_TABLE(of, hibvt_pwm_of_match);
+
+static struct platform_driver hibvt_pwm_driver = {
+ .driver = {
+ .name = "hibvt-pwm",
+ .of_match_table = hibvt_pwm_of_match,
+ },
+ .probe = hibvt_pwm_probe,
+ .remove = hibvt_pwm_remove,
+};
+module_platform_driver(hibvt_pwm_driver);
+
+MODULE_AUTHOR("Jian Yuan");
+MODULE_DESCRIPTION("HiSilicon BVT SoCs PWM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 9d5bd7d5c610..045ef9fa6fe3 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -524,7 +524,6 @@ static struct platform_driver meson_pwm_driver = {
};
module_platform_driver(meson_pwm_driver);
-MODULE_ALIAS("platform:meson-pwm");
MODULE_DESCRIPTION("Amlogic Meson PWM Generator driver");
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 06d9fa2f3bc0..172dc966a01f 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -94,5 +94,6 @@ config RESET_ZYNQ
source "drivers/reset/sti/Kconfig"
source "drivers/reset/hisilicon/Kconfig"
+source "drivers/reset/tegra/Kconfig"
endif
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index bbe7026617fc..13b346e03d84 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,6 +1,7 @@
obj-y += core.o
obj-y += hisilicon/
obj-$(CONFIG_ARCH_STI) += sti/
+obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index b8ae1dbd4c17..10368ed8fd13 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -32,6 +32,9 @@ static LIST_HEAD(reset_controller_list);
* @refcnt: Number of gets of this reset_control
* @shared: Is this a shared (1), or an exclusive (0) reset_control?
* @deassert_cnt: Number of times this reset line has been deasserted
+ * @triggered_count: Number of times this reset line has been reset. Currently
+ * only used for shared resets, which means that the value
+ * will be either 0 or 1.
*/
struct reset_control {
struct reset_controller_dev *rcdev;
@@ -40,6 +43,7 @@ struct reset_control {
unsigned int refcnt;
int shared;
atomic_t deassert_count;
+ atomic_t triggered_count;
};
/**
@@ -134,18 +138,35 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register);
* reset_control_reset - reset the controlled device
* @rstc: reset controller
*
- * Calling this on a shared reset controller is an error.
+ * On a shared reset line the actual reset pulse is only triggered once for the
+ * lifetime of the reset_control instance: for all but the first caller this is
+ * a no-op.
+ * Consumers must not use reset_control_(de)assert on shared reset lines when
+ * reset_control_reset has been used.
*/
int reset_control_reset(struct reset_control *rstc)
{
- if (WARN_ON(IS_ERR_OR_NULL(rstc)) ||
- WARN_ON(rstc->shared))
+ int ret;
+
+ if (WARN_ON(IS_ERR_OR_NULL(rstc)))
return -EINVAL;
- if (rstc->rcdev->ops->reset)
- return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
+ if (!rstc->rcdev->ops->reset)
+ return -ENOTSUPP;
- return -ENOTSUPP;
+ if (rstc->shared) {
+ if (WARN_ON(atomic_read(&rstc->deassert_count) != 0))
+ return -EINVAL;
+
+ if (atomic_inc_return(&rstc->triggered_count) != 1)
+ return 0;
+ }
+
+ ret = rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
+ if (rstc->shared && !ret)
+ atomic_dec(&rstc->triggered_count);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(reset_control_reset);
@@ -159,6 +180,8 @@ EXPORT_SYMBOL_GPL(reset_control_reset);
*
* For shared reset controls a driver cannot expect the hw's registers and
* internal state to be reset, but must be prepared for this to happen.
+ * Consumers must not use reset_control_reset on shared reset lines when
+ * reset_control_(de)assert has been used.
*/
int reset_control_assert(struct reset_control *rstc)
{
@@ -169,6 +192,9 @@ int reset_control_assert(struct reset_control *rstc)
return -ENOTSUPP;
if (rstc->shared) {
+ if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
+ return -EINVAL;
+
if (WARN_ON(atomic_read(&rstc->deassert_count) == 0))
return -EINVAL;
@@ -185,6 +211,8 @@ EXPORT_SYMBOL_GPL(reset_control_assert);
* @rstc: reset controller
*
* After calling this function, the reset is guaranteed to be deasserted.
+ * Consumers must not use reset_control_reset on shared reset lines when
+ * reset_control_(de)assert has been used.
*/
int reset_control_deassert(struct reset_control *rstc)
{
@@ -195,6 +223,9 @@ int reset_control_deassert(struct reset_control *rstc)
return -ENOTSUPP;
if (rstc->shared) {
+ if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
+ return -EINVAL;
+
if (atomic_inc_return(&rstc->deassert_count) != 1)
return 0;
}
diff --git a/drivers/reset/reset-berlin.c b/drivers/reset/reset-berlin.c
index 369f3917fd8e..371197bbd055 100644
--- a/drivers/reset/reset-berlin.c
+++ b/drivers/reset/reset-berlin.c
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2014 Marvell Technology Group Ltd.
*
+ * Marvell Berlin reset driver
+ *
* Antoine Tenart <antoine.tenart@free-electrons.com>
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
@@ -12,7 +14,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -91,7 +93,6 @@ static const struct of_device_id berlin_reset_dt_match[] = {
{ .compatible = "marvell,berlin2-reset" },
{ },
};
-MODULE_DEVICE_TABLE(of, berlin_reset_dt_match);
static struct platform_driver berlin_reset_driver = {
.probe = berlin2_reset_probe,
@@ -100,9 +101,4 @@ static struct platform_driver berlin_reset_driver = {
.of_match_table = berlin_reset_dt_match,
},
};
-module_platform_driver(berlin_reset_driver);
-
-MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
-MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
-MODULE_DESCRIPTION("Marvell Berlin reset driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(berlin_reset_driver);
diff --git a/drivers/reset/reset-lpc18xx.c b/drivers/reset/reset-lpc18xx.c
index 54cca0055171..a62ad52e262b 100644
--- a/drivers/reset/reset-lpc18xx.c
+++ b/drivers/reset/reset-lpc18xx.c
@@ -13,7 +13,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
@@ -218,39 +218,17 @@ dis_clk_reg:
return ret;
}
-static int lpc18xx_rgu_remove(struct platform_device *pdev)
-{
- struct lpc18xx_rgu_data *rc = platform_get_drvdata(pdev);
- int ret;
-
- ret = unregister_restart_handler(&rc->restart_nb);
- if (ret)
- dev_warn(&pdev->dev, "failed to unregister restart handler\n");
-
- reset_controller_unregister(&rc->rcdev);
-
- clk_disable_unprepare(rc->clk_delay);
- clk_disable_unprepare(rc->clk_reg);
-
- return 0;
-}
-
static const struct of_device_id lpc18xx_rgu_match[] = {
{ .compatible = "nxp,lpc1850-rgu" },
{ }
};
-MODULE_DEVICE_TABLE(of, lpc18xx_rgu_match);
static struct platform_driver lpc18xx_rgu_driver = {
.probe = lpc18xx_rgu_probe,
- .remove = lpc18xx_rgu_remove,
.driver = {
- .name = "lpc18xx-reset",
- .of_match_table = lpc18xx_rgu_match,
+ .name = "lpc18xx-reset",
+ .of_match_table = lpc18xx_rgu_match,
+ .suppress_bind_attrs = true,
},
};
-module_platform_driver(lpc18xx_rgu_driver);
-
-MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
-MODULE_DESCRIPTION("Reset driver for LPC18xx/43xx RGU");
-MODULE_LICENSE("GPL v2");
+builtin_platform_driver(lpc18xx_rgu_driver);
diff --git a/drivers/reset/reset-oxnas.c b/drivers/reset/reset-oxnas.c
index 944980572f79..0d9036dea010 100644
--- a/drivers/reset/reset-oxnas.c
+++ b/drivers/reset/reset-oxnas.c
@@ -80,6 +80,7 @@ static const struct reset_control_ops oxnas_reset_ops = {
static const struct of_device_id oxnas_reset_dt_ids[] = {
{ .compatible = "oxsemi,ox810se-reset", },
+ { .compatible = "oxsemi,ox820-reset", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, oxnas_reset_dt_ids);
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
index 78ebf8424375..43e4a9f39b9b 100644
--- a/drivers/reset/reset-socfpga.c
+++ b/drivers/reset/reset-socfpga.c
@@ -1,4 +1,6 @@
/*
+ * Socfpga Reset Controller Driver
+ *
* Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
*
* based on
@@ -16,7 +18,7 @@
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
@@ -148,8 +150,4 @@ static struct platform_driver socfpga_reset_driver = {
.of_match_table = socfpga_reset_dt_ids,
},
};
-module_platform_driver(socfpga_reset_driver);
-
-MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de");
-MODULE_DESCRIPTION("Socfpga Reset Controller Driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(socfpga_reset_driver);
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
index 3080190b3f90..b44f6b5f87b6 100644
--- a/drivers/reset/reset-sunxi.c
+++ b/drivers/reset/reset-sunxi.c
@@ -13,7 +13,7 @@
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -142,7 +142,6 @@ static const struct of_device_id sunxi_reset_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-clock-reset", },
{ /* sentinel */ },
};
-MODULE_DEVICE_TABLE(of, sunxi_reset_dt_ids);
static int sunxi_reset_probe(struct platform_device *pdev)
{
@@ -175,8 +174,4 @@ static struct platform_driver sunxi_reset_driver = {
.of_match_table = sunxi_reset_dt_ids,
},
};
-module_platform_driver(sunxi_reset_driver);
-
-MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
-MODULE_DESCRIPTION("Allwinner SoCs Reset Controller Driver");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sunxi_reset_driver);
diff --git a/drivers/reset/reset-zynq.c b/drivers/reset/reset-zynq.c
index 138f2f205662..87a4e355578f 100644
--- a/drivers/reset/reset-zynq.c
+++ b/drivers/reset/reset-zynq.c
@@ -3,6 +3,8 @@
*
* Xilinx Zynq Reset controller driver
*
+ * Author: Moritz Fischer <moritz.fischer@ettus.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.
@@ -15,7 +17,7 @@
#include <linux/err.h>
#include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -137,8 +139,4 @@ static struct platform_driver zynq_reset_driver = {
.of_match_table = zynq_reset_dt_ids,
},
};
-module_platform_driver(zynq_reset_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
-MODULE_DESCRIPTION("Zynq Reset Controller Driver");
+builtin_platform_driver(zynq_reset_driver);
diff --git a/drivers/reset/sti/Kconfig b/drivers/reset/sti/Kconfig
index 613178553612..71592b5bfd14 100644
--- a/drivers/reset/sti/Kconfig
+++ b/drivers/reset/sti/Kconfig
@@ -3,14 +3,6 @@ if ARCH_STI
config STI_RESET_SYSCFG
bool
-config STIH415_RESET
- bool
- select STI_RESET_SYSCFG
-
-config STIH416_RESET
- bool
- select STI_RESET_SYSCFG
-
config STIH407_RESET
bool
select STI_RESET_SYSCFG
diff --git a/drivers/reset/sti/Makefile b/drivers/reset/sti/Makefile
index dc85dfbe56a9..f9d82411f29e 100644
--- a/drivers/reset/sti/Makefile
+++ b/drivers/reset/sti/Makefile
@@ -1,5 +1,3 @@
obj-$(CONFIG_STI_RESET_SYSCFG) += reset-syscfg.o
-obj-$(CONFIG_STIH415_RESET) += reset-stih415.o
-obj-$(CONFIG_STIH416_RESET) += reset-stih416.o
obj-$(CONFIG_STIH407_RESET) += reset-stih407.o
diff --git a/drivers/reset/sti/reset-stih415.c b/drivers/reset/sti/reset-stih415.c
deleted file mode 100644
index 6f220cdbef46..000000000000
--- a/drivers/reset/sti/reset-stih415.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited
- * Author: Stephen Gallimore <stephen.gallimore@st.com>
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-
-#include <dt-bindings/reset/stih415-resets.h>
-
-#include "reset-syscfg.h"
-
-/*
- * STiH415 Peripheral powerdown definitions.
- */
-static const char stih415_front[] = "st,stih415-front-syscfg";
-static const char stih415_rear[] = "st,stih415-rear-syscfg";
-static const char stih415_sbc[] = "st,stih415-sbc-syscfg";
-static const char stih415_lpm[] = "st,stih415-lpm-syscfg";
-
-#define STIH415_PDN_FRONT(_bit) \
- _SYSCFG_RST_CH(stih415_front, SYSCFG_114, _bit, SYSSTAT_187, _bit)
-
-#define STIH415_PDN_REAR(_cntl, _stat) \
- _SYSCFG_RST_CH(stih415_rear, SYSCFG_336, _cntl, SYSSTAT_384, _stat)
-
-#define STIH415_SRST_REAR(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih415_rear, _reg, _bit)
-
-#define STIH415_SRST_SBC(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih415_sbc, _reg, _bit)
-
-#define STIH415_SRST_FRONT(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih415_front, _reg, _bit)
-
-#define STIH415_SRST_LPM(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih415_lpm, _reg, _bit)
-
-#define SYSCFG_114 0x38 /* Powerdown request EMI/NAND/Keyscan */
-#define SYSSTAT_187 0x15c /* Powerdown status EMI/NAND/Keyscan */
-
-#define SYSCFG_336 0x90 /* Powerdown request USB/SATA/PCIe */
-#define SYSSTAT_384 0x150 /* Powerdown status USB/SATA/PCIe */
-
-#define SYSCFG_376 0x130 /* Reset generator 0 control 0 */
-#define SYSCFG_166 0x108 /* Softreset Ethernet 0 */
-#define SYSCFG_31 0x7c /* Softreset Ethernet 1 */
-#define LPM_SYSCFG_1 0x4 /* Softreset IRB */
-
-static const struct syscfg_reset_channel_data stih415_powerdowns[] = {
- [STIH415_EMISS_POWERDOWN] = STIH415_PDN_FRONT(0),
- [STIH415_NAND_POWERDOWN] = STIH415_PDN_FRONT(1),
- [STIH415_KEYSCAN_POWERDOWN] = STIH415_PDN_FRONT(2),
- [STIH415_USB0_POWERDOWN] = STIH415_PDN_REAR(0, 0),
- [STIH415_USB1_POWERDOWN] = STIH415_PDN_REAR(1, 1),
- [STIH415_USB2_POWERDOWN] = STIH415_PDN_REAR(2, 2),
- [STIH415_SATA0_POWERDOWN] = STIH415_PDN_REAR(3, 3),
- [STIH415_SATA1_POWERDOWN] = STIH415_PDN_REAR(4, 4),
- [STIH415_PCIE_POWERDOWN] = STIH415_PDN_REAR(5, 8),
-};
-
-static const struct syscfg_reset_channel_data stih415_softresets[] = {
- [STIH415_ETH0_SOFTRESET] = STIH415_SRST_FRONT(SYSCFG_166, 0),
- [STIH415_ETH1_SOFTRESET] = STIH415_SRST_SBC(SYSCFG_31, 0),
- [STIH415_IRB_SOFTRESET] = STIH415_SRST_LPM(LPM_SYSCFG_1, 6),
- [STIH415_USB0_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 9),
- [STIH415_USB1_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 10),
- [STIH415_USB2_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 11),
- [STIH415_KEYSCAN_SOFTRESET] = STIH415_SRST_LPM(LPM_SYSCFG_1, 8),
-};
-
-static struct syscfg_reset_controller_data stih415_powerdown_controller = {
- .wait_for_ack = true,
- .nr_channels = ARRAY_SIZE(stih415_powerdowns),
- .channels = stih415_powerdowns,
-};
-
-static struct syscfg_reset_controller_data stih415_softreset_controller = {
- .wait_for_ack = false,
- .active_low = true,
- .nr_channels = ARRAY_SIZE(stih415_softresets),
- .channels = stih415_softresets,
-};
-
-static const struct of_device_id stih415_reset_match[] = {
- { .compatible = "st,stih415-powerdown",
- .data = &stih415_powerdown_controller, },
- { .compatible = "st,stih415-softreset",
- .data = &stih415_softreset_controller, },
- {},
-};
-
-static struct platform_driver stih415_reset_driver = {
- .probe = syscfg_reset_probe,
- .driver = {
- .name = "reset-stih415",
- .of_match_table = stih415_reset_match,
- },
-};
-
-static int __init stih415_reset_init(void)
-{
- return platform_driver_register(&stih415_reset_driver);
-}
-arch_initcall(stih415_reset_init);
diff --git a/drivers/reset/sti/reset-stih416.c b/drivers/reset/sti/reset-stih416.c
deleted file mode 100644
index c581d606ef0f..000000000000
--- a/drivers/reset/sti/reset-stih416.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited
- * Author: Stephen Gallimore <stephen.gallimore@st.com>
- * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-
-#include <dt-bindings/reset/stih416-resets.h>
-
-#include "reset-syscfg.h"
-
-/*
- * STiH416 Peripheral powerdown definitions.
- */
-static const char stih416_front[] = "st,stih416-front-syscfg";
-static const char stih416_rear[] = "st,stih416-rear-syscfg";
-static const char stih416_sbc[] = "st,stih416-sbc-syscfg";
-static const char stih416_lpm[] = "st,stih416-lpm-syscfg";
-static const char stih416_cpu[] = "st,stih416-cpu-syscfg";
-
-#define STIH416_PDN_FRONT(_bit) \
- _SYSCFG_RST_CH(stih416_front, SYSCFG_1500, _bit, SYSSTAT_1578, _bit)
-
-#define STIH416_PDN_REAR(_cntl, _stat) \
- _SYSCFG_RST_CH(stih416_rear, SYSCFG_2525, _cntl, SYSSTAT_2583, _stat)
-
-#define SYSCFG_1500 0x7d0 /* Powerdown request EMI/NAND/Keyscan */
-#define SYSSTAT_1578 0x908 /* Powerdown status EMI/NAND/Keyscan */
-
-#define SYSCFG_2525 0x834 /* Powerdown request USB/SATA/PCIe */
-#define SYSSTAT_2583 0x91c /* Powerdown status USB/SATA/PCIe */
-
-#define SYSCFG_2552 0x8A0 /* Reset Generator control 0 */
-#define SYSCFG_1539 0x86c /* Softreset Ethernet 0 */
-#define SYSCFG_510 0x7f8 /* Softreset Ethernet 1 */
-#define LPM_SYSCFG_1 0x4 /* Softreset IRB */
-#define SYSCFG_2553 0x8a4 /* Softreset SATA0/1, PCIE0/1 */
-#define SYSCFG_7563 0x8cc /* MPE softresets 0 */
-#define SYSCFG_7564 0x8d0 /* MPE softresets 1 */
-
-#define STIH416_SRST_CPU(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih416_cpu, _reg, _bit)
-
-#define STIH416_SRST_FRONT(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih416_front, _reg, _bit)
-
-#define STIH416_SRST_REAR(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih416_rear, _reg, _bit)
-
-#define STIH416_SRST_LPM(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih416_lpm, _reg, _bit)
-
-#define STIH416_SRST_SBC(_reg, _bit) \
- _SYSCFG_RST_CH_NO_ACK(stih416_sbc, _reg, _bit)
-
-static const struct syscfg_reset_channel_data stih416_powerdowns[] = {
- [STIH416_EMISS_POWERDOWN] = STIH416_PDN_FRONT(0),
- [STIH416_NAND_POWERDOWN] = STIH416_PDN_FRONT(1),
- [STIH416_KEYSCAN_POWERDOWN] = STIH416_PDN_FRONT(2),
- [STIH416_USB0_POWERDOWN] = STIH416_PDN_REAR(0, 0),
- [STIH416_USB1_POWERDOWN] = STIH416_PDN_REAR(1, 1),
- [STIH416_USB2_POWERDOWN] = STIH416_PDN_REAR(2, 2),
- [STIH416_USB3_POWERDOWN] = STIH416_PDN_REAR(6, 5),
- [STIH416_SATA0_POWERDOWN] = STIH416_PDN_REAR(3, 3),
- [STIH416_SATA1_POWERDOWN] = STIH416_PDN_REAR(4, 4),
- [STIH416_PCIE0_POWERDOWN] = STIH416_PDN_REAR(7, 9),
- [STIH416_PCIE1_POWERDOWN] = STIH416_PDN_REAR(5, 8),
-};
-
-static const struct syscfg_reset_channel_data stih416_softresets[] = {
- [STIH416_ETH0_SOFTRESET] = STIH416_SRST_FRONT(SYSCFG_1539, 0),
- [STIH416_ETH1_SOFTRESET] = STIH416_SRST_SBC(SYSCFG_510, 0),
- [STIH416_IRB_SOFTRESET] = STIH416_SRST_LPM(LPM_SYSCFG_1, 6),
- [STIH416_USB0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 9),
- [STIH416_USB1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 10),
- [STIH416_USB2_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 11),
- [STIH416_USB3_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 28),
- [STIH416_SATA0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 7),
- [STIH416_SATA1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 3),
- [STIH416_PCIE0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 15),
- [STIH416_PCIE1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 2),
- [STIH416_AUD_DAC_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 14),
- [STIH416_HDTVOUT_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 5),
- [STIH416_VTAC_M_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 25),
- [STIH416_VTAC_A_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 26),
- [STIH416_SYNC_HD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 5),
- [STIH416_SYNC_SD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 6),
- [STIH416_BLITTER_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 10),
- [STIH416_GPU_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 11),
- [STIH416_VTAC_M_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 18),
- [STIH416_VTAC_A_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 19),
- [STIH416_VTG_AUX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 21),
- [STIH416_JPEG_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 23),
- [STIH416_HVA_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 2),
- [STIH416_COMPO_M_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 3),
- [STIH416_COMPO_A_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 4),
- [STIH416_VP8_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 10),
- [STIH416_VTG_MAIN_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 16),
- [STIH416_KEYSCAN_SOFTRESET] = STIH416_SRST_LPM(LPM_SYSCFG_1, 8),
-};
-
-static struct syscfg_reset_controller_data stih416_powerdown_controller = {
- .wait_for_ack = true,
- .nr_channels = ARRAY_SIZE(stih416_powerdowns),
- .channels = stih416_powerdowns,
-};
-
-static struct syscfg_reset_controller_data stih416_softreset_controller = {
- .wait_for_ack = false,
- .active_low = true,
- .nr_channels = ARRAY_SIZE(stih416_softresets),
- .channels = stih416_softresets,
-};
-
-static const struct of_device_id stih416_reset_match[] = {
- { .compatible = "st,stih416-powerdown",
- .data = &stih416_powerdown_controller, },
- { .compatible = "st,stih416-softreset",
- .data = &stih416_softreset_controller, },
- {},
-};
-
-static struct platform_driver stih416_reset_driver = {
- .probe = syscfg_reset_probe,
- .driver = {
- .name = "reset-stih416",
- .of_match_table = stih416_reset_match,
- },
-};
-
-static int __init stih416_reset_init(void)
-{
- return platform_driver_register(&stih416_reset_driver);
-}
-arch_initcall(stih416_reset_init);
diff --git a/drivers/reset/tegra/Kconfig b/drivers/reset/tegra/Kconfig
new file mode 100644
index 000000000000..d2afa293df7d
--- /dev/null
+++ b/drivers/reset/tegra/Kconfig
@@ -0,0 +1,2 @@
+config RESET_TEGRA_BPMP
+ def_bool TEGRA_BPMP
diff --git a/drivers/reset/tegra/Makefile b/drivers/reset/tegra/Makefile
new file mode 100644
index 000000000000..775243ab7383
--- /dev/null
+++ b/drivers/reset/tegra/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RESET_TEGRA_BPMP) += reset-bpmp.o
diff --git a/drivers/reset/tegra/reset-bpmp.c b/drivers/reset/tegra/reset-bpmp.c
new file mode 100644
index 000000000000..5daf2ee1a396
--- /dev/null
+++ b/drivers/reset/tegra/reset-bpmp.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 NVIDIA Corporation
+ *
+ * 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/reset-controller.h>
+
+#include <soc/tegra/bpmp.h>
+#include <soc/tegra/bpmp-abi.h>
+
+static struct tegra_bpmp *to_tegra_bpmp(struct reset_controller_dev *rstc)
+{
+ return container_of(rstc, struct tegra_bpmp, rstc);
+}
+
+static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
+ enum mrq_reset_commands command,
+ unsigned int id)
+{
+ struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
+ struct mrq_reset_request request;
+ struct tegra_bpmp_message msg;
+
+ memset(&request, 0, sizeof(request));
+ request.cmd = command;
+ request.reset_id = id;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.mrq = MRQ_RESET;
+ msg.tx.data = &request;
+ msg.tx.size = sizeof(request);
+
+ return tegra_bpmp_transfer(bpmp, &msg);
+}
+
+static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc,
+ unsigned long id)
+{
+ return tegra_bpmp_reset_common(rstc, CMD_RESET_MODULE, id);
+}
+
+static int tegra_bpmp_reset_assert(struct reset_controller_dev *rstc,
+ unsigned long id)
+{
+ return tegra_bpmp_reset_common(rstc, CMD_RESET_ASSERT, id);
+}
+
+static int tegra_bpmp_reset_deassert(struct reset_controller_dev *rstc,
+ unsigned long id)
+{
+ return tegra_bpmp_reset_common(rstc, CMD_RESET_DEASSERT, id);
+}
+
+static const struct reset_control_ops tegra_bpmp_reset_ops = {
+ .reset = tegra_bpmp_reset_module,
+ .assert = tegra_bpmp_reset_assert,
+ .deassert = tegra_bpmp_reset_deassert,
+};
+
+int tegra_bpmp_init_resets(struct tegra_bpmp *bpmp)
+{
+ bpmp->rstc.ops = &tegra_bpmp_reset_ops;
+ bpmp->rstc.owner = THIS_MODULE;
+ bpmp->rstc.of_node = bpmp->dev->of_node;
+ bpmp->rstc.nr_resets = bpmp->soc->num_resets;
+
+ return devm_reset_controller_register(bpmp->dev, &bpmp->rstc);
+}
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea809a61b..609bb3424c14 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -23,7 +23,7 @@ config MTK_PMIC_WRAP
config MTK_SCPSYS
bool "MediaTek SCPSYS Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
- default ARM64 && ARCH_MEDIATEK
+ default ARCH_MEDIATEK
select REGMAP
select MTK_INFRACFG
select PM_GENERIC_DOMAINS if PM
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 837effe19907..beb79162369a 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -11,17 +11,16 @@
* GNU General Public License for more details.
*/
#include <linux/clk.h>
-#include <linux/delay.h>
+#include <linux/init.h>
#include <linux/io.h>
-#include <linux/kernel.h>
#include <linux/mfd/syscon.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 <linux/soc/mediatek/infracfg.h>
+
+#include <dt-bindings/power/mt2701-power.h>
#include <dt-bindings/power/mt8173-power.h>
#define SPM_VDE_PWR_CON 0x0210
@@ -29,11 +28,17 @@
#define SPM_VEN_PWR_CON 0x0230
#define SPM_ISP_PWR_CON 0x0238
#define SPM_DIS_PWR_CON 0x023c
+#define SPM_CONN_PWR_CON 0x0280
#define SPM_VEN2_PWR_CON 0x0298
-#define SPM_AUDIO_PWR_CON 0x029c
+#define SPM_AUDIO_PWR_CON 0x029c /* MT8173 */
+#define SPM_BDP_PWR_CON 0x029c /* MT2701 */
+#define SPM_ETH_PWR_CON 0x02a0
+#define SPM_HIF_PWR_CON 0x02a4
+#define SPM_IFR_MSC_PWR_CON 0x02a8
#define SPM_MFG_2D_PWR_CON 0x02c0
#define SPM_MFG_ASYNC_PWR_CON 0x02c4
#define SPM_USB_PWR_CON 0x02cc
+
#define SPM_PWR_STATUS 0x060c
#define SPM_PWR_STATUS_2ND 0x0610
@@ -43,10 +48,15 @@
#define PWR_ON_2ND_BIT BIT(3)
#define PWR_CLK_DIS_BIT BIT(4)
+#define PWR_STATUS_CONN BIT(1)
#define PWR_STATUS_DISP BIT(3)
#define PWR_STATUS_MFG BIT(4)
#define PWR_STATUS_ISP BIT(5)
#define PWR_STATUS_VDEC BIT(7)
+#define PWR_STATUS_BDP BIT(14)
+#define PWR_STATUS_ETH BIT(15)
+#define PWR_STATUS_HIF BIT(16)
+#define PWR_STATUS_IFR_MSC BIT(17)
#define PWR_STATUS_VENC_LT BIT(20)
#define PWR_STATUS_VENC BIT(21)
#define PWR_STATUS_MFG_2D BIT(22)
@@ -55,12 +65,23 @@
#define PWR_STATUS_USB BIT(25)
enum clk_id {
- MT8173_CLK_NONE,
- MT8173_CLK_MM,
- MT8173_CLK_MFG,
- MT8173_CLK_VENC,
- MT8173_CLK_VENC_LT,
- MT8173_CLK_MAX,
+ CLK_NONE,
+ CLK_MM,
+ CLK_MFG,
+ CLK_VENC,
+ CLK_VENC_LT,
+ CLK_ETHIF,
+ CLK_MAX,
+};
+
+static const char * const clk_names[] = {
+ NULL,
+ "mm",
+ "mfg",
+ "venc",
+ "venc_lt",
+ "ethif",
+ NULL,
};
#define MAX_CLKS 2
@@ -76,98 +97,6 @@ struct scp_domain_data {
bool active_wakeup;
};
-static const struct scp_domain_data scp_domain_data[] = {
- [MT8173_POWER_DOMAIN_VDEC] = {
- .name = "vdec",
- .sta_mask = PWR_STATUS_VDEC,
- .ctl_offs = SPM_VDE_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(12, 12),
- .clk_id = {MT8173_CLK_MM},
- },
- [MT8173_POWER_DOMAIN_VENC] = {
- .name = "venc",
- .sta_mask = PWR_STATUS_VENC,
- .ctl_offs = SPM_VEN_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(15, 12),
- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
- },
- [MT8173_POWER_DOMAIN_ISP] = {
- .name = "isp",
- .sta_mask = PWR_STATUS_ISP,
- .ctl_offs = SPM_ISP_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(13, 12),
- .clk_id = {MT8173_CLK_MM},
- },
- [MT8173_POWER_DOMAIN_MM] = {
- .name = "mm",
- .sta_mask = PWR_STATUS_DISP,
- .ctl_offs = SPM_DIS_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(12, 12),
- .clk_id = {MT8173_CLK_MM},
- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
- MT8173_TOP_AXI_PROT_EN_MM_M1,
- },
- [MT8173_POWER_DOMAIN_VENC_LT] = {
- .name = "venc_lt",
- .sta_mask = PWR_STATUS_VENC_LT,
- .ctl_offs = SPM_VEN2_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(15, 12),
- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
- },
- [MT8173_POWER_DOMAIN_AUDIO] = {
- .name = "audio",
- .sta_mask = PWR_STATUS_AUDIO,
- .ctl_offs = SPM_AUDIO_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(15, 12),
- .clk_id = {MT8173_CLK_NONE},
- },
- [MT8173_POWER_DOMAIN_USB] = {
- .name = "usb",
- .sta_mask = PWR_STATUS_USB,
- .ctl_offs = SPM_USB_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(15, 12),
- .clk_id = {MT8173_CLK_NONE},
- .active_wakeup = true,
- },
- [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
- .name = "mfg_async",
- .sta_mask = PWR_STATUS_MFG_ASYNC,
- .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = 0,
- .clk_id = {MT8173_CLK_MFG},
- },
- [MT8173_POWER_DOMAIN_MFG_2D] = {
- .name = "mfg_2d",
- .sta_mask = PWR_STATUS_MFG_2D,
- .ctl_offs = SPM_MFG_2D_PWR_CON,
- .sram_pdn_bits = GENMASK(11, 8),
- .sram_pdn_ack_bits = GENMASK(13, 12),
- .clk_id = {MT8173_CLK_NONE},
- },
- [MT8173_POWER_DOMAIN_MFG] = {
- .name = "mfg",
- .sta_mask = PWR_STATUS_MFG,
- .ctl_offs = SPM_MFG_PWR_CON,
- .sram_pdn_bits = GENMASK(13, 8),
- .sram_pdn_ack_bits = GENMASK(21, 16),
- .clk_id = {MT8173_CLK_NONE},
- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
- MT8173_TOP_AXI_PROT_EN_MFG_M0 |
- MT8173_TOP_AXI_PROT_EN_MFG_M1 |
- MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
- },
-};
-
-#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
-
struct scp;
struct scp_domain {
@@ -179,7 +108,7 @@ struct scp_domain {
};
struct scp {
- struct scp_domain domains[NUM_DOMAINS];
+ struct scp_domain *domains;
struct genpd_onecell_data pd_data;
struct device *dev;
void __iomem *base;
@@ -408,57 +337,55 @@ static bool scpsys_active_wakeup(struct device *dev)
return scpd->data->active_wakeup;
}
-static int scpsys_probe(struct platform_device *pdev)
+static void init_clks(struct platform_device *pdev, struct clk **clk)
+{
+ int i;
+
+ for (i = CLK_NONE + 1; i < CLK_MAX; i++)
+ clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
+}
+
+static struct scp *init_scp(struct platform_device *pdev,
+ const struct scp_domain_data *scp_domain_data, int num)
{
struct genpd_onecell_data *pd_data;
struct resource *res;
- int i, j, ret;
+ int i, j;
struct scp *scp;
- struct clk *clk[MT8173_CLK_MAX];
+ struct clk *clk[CLK_MAX];
scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
if (!scp)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
scp->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
scp->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(scp->base))
- return PTR_ERR(scp->base);
+ return ERR_CAST(scp->base);
+
+ scp->domains = devm_kzalloc(&pdev->dev,
+ sizeof(*scp->domains) * num, GFP_KERNEL);
+ if (!scp->domains)
+ return ERR_PTR(-ENOMEM);
pd_data = &scp->pd_data;
pd_data->domains = devm_kzalloc(&pdev->dev,
- sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
+ sizeof(*pd_data->domains) * num, GFP_KERNEL);
if (!pd_data->domains)
- return -ENOMEM;
-
- clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
- if (IS_ERR(clk[MT8173_CLK_MM]))
- return PTR_ERR(clk[MT8173_CLK_MM]);
-
- clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
- if (IS_ERR(clk[MT8173_CLK_MFG]))
- return PTR_ERR(clk[MT8173_CLK_MFG]);
-
- clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
- if (IS_ERR(clk[MT8173_CLK_VENC]))
- return PTR_ERR(clk[MT8173_CLK_VENC]);
-
- clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
- if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
- return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
+ return ERR_PTR(-ENOMEM);
scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"infracfg");
if (IS_ERR(scp->infracfg)) {
dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
PTR_ERR(scp->infracfg));
- return PTR_ERR(scp->infracfg);
+ return ERR_CAST(scp->infracfg);
}
- for (i = 0; i < NUM_DOMAINS; i++) {
+ for (i = 0; i < num; i++) {
struct scp_domain *scpd = &scp->domains[i];
const struct scp_domain_data *data = &scp_domain_data[i];
@@ -467,13 +394,15 @@ static int scpsys_probe(struct platform_device *pdev)
if (PTR_ERR(scpd->supply) == -ENODEV)
scpd->supply = NULL;
else
- return PTR_ERR(scpd->supply);
+ return ERR_CAST(scpd->supply);
}
}
- pd_data->num_domains = NUM_DOMAINS;
+ pd_data->num_domains = num;
+
+ init_clks(pdev, clk);
- for (i = 0; i < NUM_DOMAINS; i++) {
+ for (i = 0; i < num; i++) {
struct scp_domain *scpd = &scp->domains[i];
struct generic_pm_domain *genpd = &scpd->genpd;
const struct scp_domain_data *data = &scp_domain_data[i];
@@ -482,13 +411,37 @@ static int scpsys_probe(struct platform_device *pdev)
scpd->scp = scp;
scpd->data = data;
- for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
- scpd->clk[j] = clk[data->clk_id[j]];
+
+ for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
+ struct clk *c = clk[data->clk_id[j]];
+
+ if (IS_ERR(c)) {
+ dev_err(&pdev->dev, "%s: clk unavailable\n",
+ data->name);
+ return ERR_CAST(c);
+ }
+
+ scpd->clk[j] = c;
+ }
genpd->name = data->name;
genpd->power_off = scpsys_power_off;
genpd->power_on = scpsys_power_on;
genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
+ }
+
+ return scp;
+}
+
+static void mtk_register_power_domains(struct platform_device *pdev,
+ struct scp *scp, int num)
+{
+ struct genpd_onecell_data *pd_data;
+ int i, ret;
+
+ for (i = 0; i < num; i++) {
+ struct scp_domain *scpd = &scp->domains[i];
+ struct generic_pm_domain *genpd = &scpd->genpd;
/*
* Initially turn on all domains to make the domains usable
@@ -507,6 +460,222 @@ static int scpsys_probe(struct platform_device *pdev)
* valid.
*/
+ pd_data = &scp->pd_data;
+
+ ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
+}
+
+/*
+ * MT2701 power domain support
+ */
+
+static const struct scp_domain_data scp_domain_data_mt2701[] = {
+ [MT2701_POWER_DOMAIN_CONN] = {
+ .name = "conn",
+ .sta_mask = PWR_STATUS_CONN,
+ .ctl_offs = SPM_CONN_PWR_CON,
+ .bus_prot_mask = 0x0104,
+ .clk_id = {CLK_NONE},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_DISP] = {
+ .name = "disp",
+ .sta_mask = PWR_STATUS_DISP,
+ .ctl_offs = SPM_DIS_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .clk_id = {CLK_MM},
+ .bus_prot_mask = 0x0002,
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_MFG] = {
+ .name = "mfg",
+ .sta_mask = PWR_STATUS_MFG,
+ .ctl_offs = SPM_MFG_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .clk_id = {CLK_MFG},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_VDEC] = {
+ .name = "vdec",
+ .sta_mask = PWR_STATUS_VDEC,
+ .ctl_offs = SPM_VDE_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .clk_id = {CLK_MM},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_ISP] = {
+ .name = "isp",
+ .sta_mask = PWR_STATUS_ISP,
+ .ctl_offs = SPM_ISP_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(13, 12),
+ .clk_id = {CLK_MM},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_BDP] = {
+ .name = "bdp",
+ .sta_mask = PWR_STATUS_BDP,
+ .ctl_offs = SPM_BDP_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .clk_id = {CLK_NONE},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_ETH] = {
+ .name = "eth",
+ .sta_mask = PWR_STATUS_ETH,
+ .ctl_offs = SPM_ETH_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .clk_id = {CLK_ETHIF},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_HIF] = {
+ .name = "hif",
+ .sta_mask = PWR_STATUS_HIF,
+ .ctl_offs = SPM_HIF_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .clk_id = {CLK_ETHIF},
+ .active_wakeup = true,
+ },
+ [MT2701_POWER_DOMAIN_IFR_MSC] = {
+ .name = "ifr_msc",
+ .sta_mask = PWR_STATUS_IFR_MSC,
+ .ctl_offs = SPM_IFR_MSC_PWR_CON,
+ .clk_id = {CLK_NONE},
+ .active_wakeup = true,
+ },
+};
+
+#define NUM_DOMAINS_MT2701 ARRAY_SIZE(scp_domain_data_mt2701)
+
+static int __init scpsys_probe_mt2701(struct platform_device *pdev)
+{
+ struct scp *scp;
+
+ scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
+ if (IS_ERR(scp))
+ return PTR_ERR(scp);
+
+ mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);
+
+ return 0;
+}
+
+/*
+ * MT8173 power domain support
+ */
+
+static const struct scp_domain_data scp_domain_data_mt8173[] = {
+ [MT8173_POWER_DOMAIN_VDEC] = {
+ .name = "vdec",
+ .sta_mask = PWR_STATUS_VDEC,
+ .ctl_offs = SPM_VDE_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .clk_id = {CLK_MM},
+ },
+ [MT8173_POWER_DOMAIN_VENC] = {
+ .name = "venc",
+ .sta_mask = PWR_STATUS_VENC,
+ .ctl_offs = SPM_VEN_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .clk_id = {CLK_MM, CLK_VENC},
+ },
+ [MT8173_POWER_DOMAIN_ISP] = {
+ .name = "isp",
+ .sta_mask = PWR_STATUS_ISP,
+ .ctl_offs = SPM_ISP_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(13, 12),
+ .clk_id = {CLK_MM},
+ },
+ [MT8173_POWER_DOMAIN_MM] = {
+ .name = "mm",
+ .sta_mask = PWR_STATUS_DISP,
+ .ctl_offs = SPM_DIS_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ .clk_id = {CLK_MM},
+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
+ MT8173_TOP_AXI_PROT_EN_MM_M1,
+ },
+ [MT8173_POWER_DOMAIN_VENC_LT] = {
+ .name = "venc_lt",
+ .sta_mask = PWR_STATUS_VENC_LT,
+ .ctl_offs = SPM_VEN2_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .clk_id = {CLK_MM, CLK_VENC_LT},
+ },
+ [MT8173_POWER_DOMAIN_AUDIO] = {
+ .name = "audio",
+ .sta_mask = PWR_STATUS_AUDIO,
+ .ctl_offs = SPM_AUDIO_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .clk_id = {CLK_NONE},
+ },
+ [MT8173_POWER_DOMAIN_USB] = {
+ .name = "usb",
+ .sta_mask = PWR_STATUS_USB,
+ .ctl_offs = SPM_USB_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .clk_id = {CLK_NONE},
+ .active_wakeup = true,
+ },
+ [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
+ .name = "mfg_async",
+ .sta_mask = PWR_STATUS_MFG_ASYNC,
+ .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = 0,
+ .clk_id = {CLK_MFG},
+ },
+ [MT8173_POWER_DOMAIN_MFG_2D] = {
+ .name = "mfg_2d",
+ .sta_mask = PWR_STATUS_MFG_2D,
+ .ctl_offs = SPM_MFG_2D_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(13, 12),
+ .clk_id = {CLK_NONE},
+ },
+ [MT8173_POWER_DOMAIN_MFG] = {
+ .name = "mfg",
+ .sta_mask = PWR_STATUS_MFG,
+ .ctl_offs = SPM_MFG_PWR_CON,
+ .sram_pdn_bits = GENMASK(13, 8),
+ .sram_pdn_ack_bits = GENMASK(21, 16),
+ .clk_id = {CLK_NONE},
+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
+ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
+ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
+ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
+ },
+};
+
+#define NUM_DOMAINS_MT8173 ARRAY_SIZE(scp_domain_data_mt8173)
+
+static int __init scpsys_probe_mt8173(struct platform_device *pdev)
+{
+ struct scp *scp;
+ struct genpd_onecell_data *pd_data;
+ int ret;
+
+ scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
+ if (IS_ERR(scp))
+ return PTR_ERR(scp);
+
+ mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
+
+ pd_data = &scp->pd_data;
+
ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
if (ret && IS_ENABLED(CONFIG_PM))
@@ -517,21 +686,39 @@ static int scpsys_probe(struct platform_device *pdev)
if (ret && IS_ENABLED(CONFIG_PM))
dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
- ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
- if (ret)
- dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
-
return 0;
}
+/*
+ * scpsys driver init
+ */
+
static const struct of_device_id of_scpsys_match_tbl[] = {
{
+ .compatible = "mediatek,mt2701-scpsys",
+ .data = scpsys_probe_mt2701,
+ }, {
.compatible = "mediatek,mt8173-scpsys",
+ .data = scpsys_probe_mt8173,
}, {
/* sentinel */
}
};
+static int scpsys_probe(struct platform_device *pdev)
+{
+ int (*probe)(struct platform_device *);
+ const struct of_device_id *of_id;
+
+ of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ probe = of_id->data;
+
+ return probe(pdev);
+}
+
static struct platform_driver scpsys_drv = {
.probe = scpsys_probe,
.driver = {
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index 86cc78cd1962..d9115cb5ed9d 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -1,8 +1,12 @@
+obj-$(CONFIG_SOC_BUS) += renesas-soc.o
+
obj-$(CONFIG_ARCH_RCAR_GEN1) += rcar-rst.o
obj-$(CONFIG_ARCH_RCAR_GEN2) += rcar-rst.o
obj-$(CONFIG_ARCH_R8A7795) += rcar-rst.o
obj-$(CONFIG_ARCH_R8A7796) += rcar-rst.o
+obj-$(CONFIG_ARCH_R8A7743) += rcar-sysc.o r8a7743-sysc.o
+obj-$(CONFIG_ARCH_R8A7745) += rcar-sysc.o r8a7745-sysc.o
obj-$(CONFIG_ARCH_R8A7779) += rcar-sysc.o r8a7779-sysc.o
obj-$(CONFIG_ARCH_R8A7790) += rcar-sysc.o r8a7790-sysc.o
obj-$(CONFIG_ARCH_R8A7791) += rcar-sysc.o r8a7791-sysc.o
diff --git a/drivers/soc/renesas/r8a7743-sysc.c b/drivers/soc/renesas/r8a7743-sysc.c
new file mode 100644
index 000000000000..9583a327d90c
--- /dev/null
+++ b/drivers/soc/renesas/r8a7743-sysc.c
@@ -0,0 +1,32 @@
+/*
+ * Renesas RZ/G1M System Controller
+ *
+ * Copyright (C) 2016 Cogent Embedded Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation; of the License.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a7743-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a7743_areas[] __initconst = {
+ { "always-on", 0, 0, R8A7743_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+ { "ca15-scu", 0x180, 0, R8A7743_PD_CA15_SCU, R8A7743_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca15-cpu0", 0x40, 0, R8A7743_PD_CA15_CPU0, R8A7743_PD_CA15_SCU,
+ PD_CPU_NOCR },
+ { "ca15-cpu1", 0x40, 1, R8A7743_PD_CA15_CPU1, R8A7743_PD_CA15_SCU,
+ PD_CPU_NOCR },
+ { "sgx", 0xc0, 0, R8A7743_PD_SGX, R8A7743_PD_ALWAYS_ON },
+};
+
+const struct rcar_sysc_info r8a7743_sysc_info __initconst = {
+ .areas = r8a7743_areas,
+ .num_areas = ARRAY_SIZE(r8a7743_areas),
+};
diff --git a/drivers/soc/renesas/r8a7745-sysc.c b/drivers/soc/renesas/r8a7745-sysc.c
new file mode 100644
index 000000000000..d17887c08aa1
--- /dev/null
+++ b/drivers/soc/renesas/r8a7745-sysc.c
@@ -0,0 +1,32 @@
+/*
+ * Renesas RZ/G1E System Controller
+ *
+ * Copyright (C) 2016 Cogent Embedded Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation; of the License.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a7745-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a7745_areas[] __initconst = {
+ { "always-on", 0, 0, R8A7745_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+ { "ca7-scu", 0x100, 0, R8A7745_PD_CA7_SCU, R8A7745_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca7-cpu0", 0x1c0, 0, R8A7745_PD_CA7_CPU0, R8A7745_PD_CA7_SCU,
+ PD_CPU_NOCR },
+ { "ca7-cpu1", 0x1c0, 1, R8A7745_PD_CA7_CPU1, R8A7745_PD_CA7_SCU,
+ PD_CPU_NOCR },
+ { "sgx", 0xc0, 0, R8A7745_PD_SGX, R8A7745_PD_ALWAYS_ON },
+};
+
+const struct rcar_sysc_info r8a7745_sysc_info __initconst = {
+ .areas = r8a7745_areas,
+ .num_areas = ARRAY_SIZE(r8a7745_areas),
+};
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 65c8e1eb90c0..225c35c79d9a 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -275,6 +275,12 @@ finalize:
}
static const struct of_device_id rcar_sysc_matches[] = {
+#ifdef CONFIG_ARCH_R8A7743
+ { .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
+#endif
+#ifdef CONFIG_ARCH_R8A7745
+ { .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info },
+#endif
#ifdef CONFIG_ARCH_R8A7779
{ .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
#endif
diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
index 77dbe861473f..f6e842e2976e 100644
--- a/drivers/soc/renesas/rcar-sysc.h
+++ b/drivers/soc/renesas/rcar-sysc.h
@@ -50,6 +50,8 @@ struct rcar_sysc_info {
unsigned int num_areas;
};
+extern const struct rcar_sysc_info r8a7743_sysc_info;
+extern const struct rcar_sysc_info r8a7745_sysc_info;
extern const struct rcar_sysc_info r8a7779_sysc_info;
extern const struct rcar_sysc_info r8a7790_sysc_info;
extern const struct rcar_sysc_info r8a7791_sysc_info;
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
new file mode 100644
index 000000000000..330960312296
--- /dev/null
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -0,0 +1,257 @@
+/*
+ * Renesas SoC Identification
+ *
+ * Copyright (C) 2014-2016 Glider bvba
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sys_soc.h>
+
+
+struct renesas_family {
+ const char name[16];
+ u32 reg; /* CCCR or PRR, if not in DT */
+};
+
+static const struct renesas_family fam_rcar_gen1 __initconst __maybe_unused = {
+ .name = "R-Car Gen1",
+ .reg = 0xff000044, /* PRR (Product Register) */
+};
+
+static const struct renesas_family fam_rcar_gen2 __initconst __maybe_unused = {
+ .name = "R-Car Gen2",
+ .reg = 0xff000044, /* PRR (Product Register) */
+};
+
+static const struct renesas_family fam_rcar_gen3 __initconst __maybe_unused = {
+ .name = "R-Car Gen3",
+ .reg = 0xfff00044, /* PRR (Product Register) */
+};
+
+static const struct renesas_family fam_rmobile __initconst __maybe_unused = {
+ .name = "R-Mobile",
+ .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
+};
+
+static const struct renesas_family fam_rza __initconst __maybe_unused = {
+ .name = "RZ/A",
+};
+
+static const struct renesas_family fam_rzg __initconst __maybe_unused = {
+ .name = "RZ/G",
+ .reg = 0xff000044, /* PRR (Product Register) */
+};
+
+static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
+ .name = "SH-Mobile",
+ .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
+};
+
+
+struct renesas_soc {
+ const struct renesas_family *family;
+ u8 id;
+};
+
+static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = {
+ .family = &fam_rza,
+};
+
+static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = {
+ .family = &fam_rmobile,
+ .id = 0x3f,
+};
+
+static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = {
+ .family = &fam_rmobile,
+ .id = 0x40,
+};
+
+static const struct renesas_soc soc_rz_g1m __initconst __maybe_unused = {
+ .family = &fam_rzg,
+ .id = 0x47,
+};
+
+static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = {
+ .family = &fam_rzg,
+ .id = 0x4c,
+};
+
+static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
+ .family = &fam_rcar_gen1,
+};
+
+static const struct renesas_soc soc_rcar_h1 __initconst __maybe_unused = {
+ .family = &fam_rcar_gen1,
+ .id = 0x3b,
+};
+
+static const struct renesas_soc soc_rcar_h2 __initconst __maybe_unused = {
+ .family = &fam_rcar_gen2,
+ .id = 0x45,
+};
+
+static const struct renesas_soc soc_rcar_m2_w __initconst __maybe_unused = {
+ .family = &fam_rcar_gen2,
+ .id = 0x47,
+};
+
+static const struct renesas_soc soc_rcar_v2h __initconst __maybe_unused = {
+ .family = &fam_rcar_gen2,
+ .id = 0x4a,
+};
+
+static const struct renesas_soc soc_rcar_m2_n __initconst __maybe_unused = {
+ .family = &fam_rcar_gen2,
+ .id = 0x4b,
+};
+
+static const struct renesas_soc soc_rcar_e2 __initconst __maybe_unused = {
+ .family = &fam_rcar_gen2,
+ .id = 0x4c,
+};
+
+static const struct renesas_soc soc_rcar_h3 __initconst __maybe_unused = {
+ .family = &fam_rcar_gen3,
+ .id = 0x4f,
+};
+
+static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = {
+ .family = &fam_rcar_gen3,
+ .id = 0x52,
+};
+
+static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
+ .family = &fam_shmobile,
+ .id = 0x37,
+};
+
+
+static const struct of_device_id renesas_socs[] __initconst = {
+#ifdef CONFIG_ARCH_R7S72100
+ { .compatible = "renesas,r7s72100", .data = &soc_rz_a1h },
+#endif
+#ifdef CONFIG_ARCH_R8A73A4
+ { .compatible = "renesas,r8a73a4", .data = &soc_rmobile_ape6 },
+#endif
+#ifdef CONFIG_ARCH_R8A7740
+ { .compatible = "renesas,r8a7740", .data = &soc_rmobile_a1 },
+#endif
+#ifdef CONFIG_ARCH_R8A7743
+ { .compatible = "renesas,r8a7743", .data = &soc_rz_g1m },
+#endif
+#ifdef CONFIG_ARCH_R8A7745
+ { .compatible = "renesas,r8a7745", .data = &soc_rz_g1e },
+#endif
+#ifdef CONFIG_ARCH_R8A7778
+ { .compatible = "renesas,r8a7778", .data = &soc_rcar_m1a },
+#endif
+#ifdef CONFIG_ARCH_R8A7779
+ { .compatible = "renesas,r8a7779", .data = &soc_rcar_h1 },
+#endif
+#ifdef CONFIG_ARCH_R8A7790
+ { .compatible = "renesas,r8a7790", .data = &soc_rcar_h2 },
+#endif
+#ifdef CONFIG_ARCH_R8A7791
+ { .compatible = "renesas,r8a7791", .data = &soc_rcar_m2_w },
+#endif
+#ifdef CONFIG_ARCH_R8A7792
+ { .compatible = "renesas,r8a7792", .data = &soc_rcar_v2h },
+#endif
+#ifdef CONFIG_ARCH_R8A7793
+ { .compatible = "renesas,r8a7793", .data = &soc_rcar_m2_n },
+#endif
+#ifdef CONFIG_ARCH_R8A7794
+ { .compatible = "renesas,r8a7794", .data = &soc_rcar_e2 },
+#endif
+#ifdef CONFIG_ARCH_R8A7795
+ { .compatible = "renesas,r8a7795", .data = &soc_rcar_h3 },
+#endif
+#ifdef CONFIG_ARCH_R8A7796
+ { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w },
+#endif
+#ifdef CONFIG_ARCH_SH73A0
+ { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
+#endif
+ { /* sentinel */ }
+};
+
+static int __init renesas_soc_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ const struct renesas_family *family;
+ const struct of_device_id *match;
+ const struct renesas_soc *soc;
+ void __iomem *chipid = NULL;
+ struct soc_device *soc_dev;
+ struct device_node *np;
+ unsigned int product;
+
+ match = of_match_node(renesas_socs, of_root);
+ if (!match)
+ return -ENODEV;
+
+ soc = match->data;
+ family = soc->family;
+
+ /* Try PRR first, then hardcoded fallback */
+ np = of_find_compatible_node(NULL, NULL, "renesas,prr");
+ if (np) {
+ chipid = of_iomap(np, 0);
+ of_node_put(np);
+ } else if (soc->id) {
+ chipid = ioremap(family->reg, 4);
+ }
+ if (chipid) {
+ product = readl(chipid);
+ iounmap(chipid);
+ if (soc->id && ((product >> 8) & 0xff) != soc->id) {
+ pr_warn("SoC mismatch (product = 0x%x)\n", product);
+ return -ENODEV;
+ }
+ }
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENOMEM;
+
+ np = of_find_node_by_path("/");
+ of_property_read_string(np, "model", &soc_dev_attr->machine);
+ of_node_put(np);
+
+ soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
+ soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1,
+ GFP_KERNEL);
+ if (chipid)
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
+ ((product >> 4) & 0x0f) + 1,
+ product & 0xf);
+
+ pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family,
+ soc_dev_attr->soc_id, soc_dev_attr->revision ?: "");
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ kfree(soc_dev_attr->revision);
+ kfree_const(soc_dev_attr->soc_id);
+ kfree_const(soc_dev_attr->family);
+ kfree(soc_dev_attr);
+ return PTR_ERR(soc_dev);
+ }
+
+ return 0;
+}
+core_initcall(renesas_soc_init);
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 7acd1517dd37..1c78c42416c6 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -9,6 +9,7 @@
*/
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/err.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
@@ -105,12 +106,24 @@ static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
return (val & pd_info->idle_mask) == pd_info->idle_mask;
}
+static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
+{
+ unsigned int val;
+
+ regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
+ return val;
+}
+
static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
bool idle)
{
const struct rockchip_domain_info *pd_info = pd->info;
+ struct generic_pm_domain *genpd = &pd->genpd;
struct rockchip_pmu *pmu = pd->pmu;
+ unsigned int target_ack;
unsigned int val;
+ bool is_idle;
+ int ret;
if (pd_info->req_mask == 0)
return 0;
@@ -120,12 +133,26 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
dsb(sy);
- do {
- regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
- } while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0));
+ /* Wait util idle_ack = 1 */
+ target_ack = idle ? pd_info->ack_mask : 0;
+ ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
+ (val & pd_info->ack_mask) == target_ack,
+ 0, 10000);
+ if (ret) {
+ dev_err(pmu->dev,
+ "failed to get ack on domain '%s', val=0x%x\n",
+ genpd->name, val);
+ return ret;
+ }
- while (rockchip_pmu_domain_is_idle(pd) != idle)
- cpu_relax();
+ ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_idle, pd,
+ is_idle, is_idle == idle, 0, 10000);
+ if (ret) {
+ dev_err(pmu->dev,
+ "failed to set idle on domain '%s', val=%d\n",
+ genpd->name, is_idle);
+ return ret;
+ }
return 0;
}
@@ -198,6 +225,8 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
bool on)
{
struct rockchip_pmu *pmu = pd->pmu;
+ struct generic_pm_domain *genpd = &pd->genpd;
+ bool is_on;
if (pd->info->pwr_mask == 0)
return;
@@ -207,8 +236,13 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
dsb(sy);
- while (rockchip_pmu_domain_is_on(pd) != on)
- cpu_relax();
+ if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
+ is_on == on, 0, 10000)) {
+ dev_err(pmu->dev,
+ "failed to set domain '%s', val=%d\n",
+ genpd->name, is_on);
+ return;
+ }
}
static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
@@ -445,7 +479,16 @@ err_out:
static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
{
- int i;
+ int i, ret;
+
+ /*
+ * We're in the error cleanup already, so we only complain,
+ * but won't emit another error on top of the original one.
+ */
+ ret = pm_genpd_remove(&pd->genpd);
+ if (ret < 0)
+ dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n",
+ pd->genpd.name, ret);
for (i = 0; i < pd->num_clks; i++) {
clk_unprepare(pd->clks[i]);
@@ -597,10 +640,12 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
* Configure power up and down transition delays for CORE
* and GPU domains.
*/
- rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
- pmu_info->core_power_transition_time);
- rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
- pmu_info->gpu_power_transition_time);
+ if (pmu_info->core_power_transition_time)
+ rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
+ pmu_info->core_power_transition_time);
+ if (pmu_info->gpu_pwrcnt_offset)
+ rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
+ pmu_info->gpu_power_transition_time);
error = -ENODEV;
@@ -627,7 +672,11 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
goto err_out;
}
- of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+ error = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+ if (error) {
+ dev_err(dev, "failed to add provider: %d\n", error);
+ goto err_out;
+ }
return 0;
@@ -722,11 +771,7 @@ static const struct rockchip_pmu_info rk3399_pmu = {
.idle_offset = 0x64,
.ack_offset = 0x68,
- .core_pwrcnt_offset = 0x9c,
- .gpu_pwrcnt_offset = 0xa4,
-
- .core_power_transition_time = 24,
- .gpu_power_transition_time = 24,
+ /* ARM Trusted Firmware manages power transition times */
.num_domains = ARRAY_SIZE(rk3399_pm_domains),
.domain_info = rk3399_pm_domains,
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 03089ad2fc65..e5e124c07066 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -77,5 +77,19 @@ config ARCH_TEGRA_210_SOC
controllers, such as GPIO, I2C, SPI, SDHCI, PCIe, SATA and XHCI, to
name only a few.
+config ARCH_TEGRA_186_SOC
+ bool "NVIDIA Tegra186 SoC"
+ select MAILBOX
+ select TEGRA_BPMP
+ select TEGRA_HSP_MBOX
+ select TEGRA_IVC
+ help
+ Enable support for the NVIDIA Tegar186 SoC. The Tegra186 features a
+ combination of Denver and Cortex-A57 CPU cores and a GPU based on
+ the Pascal architecture. It contains an ADSP with a Cortex-A9 CPU
+ used for audio processing, hardware video encoders/decoders with
+ multi-format support, ISP for image capture processing and BPMP for
+ power management.
+
endif
endif
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 7792ed88d80b..e233dd5dcab3 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -45,29 +45,31 @@
#include <soc/tegra/pmc.h>
#define PMC_CNTRL 0x0
-#define PMC_CNTRL_SYSCLK_POLARITY (1 << 10) /* sys clk polarity */
-#define PMC_CNTRL_SYSCLK_OE (1 << 11) /* system clock enable */
-#define PMC_CNTRL_SIDE_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */
-#define PMC_CNTRL_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */
-#define PMC_CNTRL_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */
-#define PMC_CNTRL_INTR_POLARITY (1 << 17) /* inverts INTR polarity */
-#define PMC_CNTRL_MAIN_RST (1 << 4)
+#define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
+#define PMC_CNTRL_CPU_PWRREQ_OE BIT(16) /* CPU pwr req enable */
+#define PMC_CNTRL_CPU_PWRREQ_POLARITY BIT(15) /* CPU pwr req polarity */
+#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14) /* LP0 when CPU pwr gated */
+#define PMC_CNTRL_SYSCLK_OE BIT(11) /* system clock enable */
+#define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */
+#define PMC_CNTRL_MAIN_RST BIT(4)
#define DPD_SAMPLE 0x020
-#define DPD_SAMPLE_ENABLE (1 << 0)
+#define DPD_SAMPLE_ENABLE BIT(0)
#define DPD_SAMPLE_DISABLE (0 << 0)
#define PWRGATE_TOGGLE 0x30
-#define PWRGATE_TOGGLE_START (1 << 8)
+#define PWRGATE_TOGGLE_START BIT(8)
#define REMOVE_CLAMPING 0x34
#define PWRGATE_STATUS 0x38
+#define PMC_PWR_DET 0x48
+
#define PMC_SCRATCH0 0x50
-#define PMC_SCRATCH0_MODE_RECOVERY (1 << 31)
-#define PMC_SCRATCH0_MODE_BOOTLOADER (1 << 30)
-#define PMC_SCRATCH0_MODE_RCM (1 << 1)
+#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
+#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
+#define PMC_SCRATCH0_MODE_RCM BIT(1)
#define PMC_SCRATCH0_MODE_MASK (PMC_SCRATCH0_MODE_RECOVERY | \
PMC_SCRATCH0_MODE_BOOTLOADER | \
PMC_SCRATCH0_MODE_RCM)
@@ -75,11 +77,13 @@
#define PMC_CPUPWRGOOD_TIMER 0xc8
#define PMC_CPUPWROFF_TIMER 0xcc
+#define PMC_PWR_DET_VALUE 0xe4
+
#define PMC_SCRATCH41 0x140
#define PMC_SENSOR_CTRL 0x1b0
-#define PMC_SENSOR_CTRL_SCRATCH_WRITE (1 << 2)
-#define PMC_SENSOR_CTRL_ENABLE_RST (1 << 1)
+#define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
+#define PMC_SENSOR_CTRL_ENABLE_RST BIT(1)
#define PMC_RST_STATUS 0x1b4
#define PMC_RST_STATUS_POR 0
@@ -90,10 +94,10 @@
#define PMC_RST_STATUS_AOTAG 5
#define IO_DPD_REQ 0x1b8
-#define IO_DPD_REQ_CODE_IDLE (0 << 30)
-#define IO_DPD_REQ_CODE_OFF (1 << 30)
-#define IO_DPD_REQ_CODE_ON (2 << 30)
-#define IO_DPD_REQ_CODE_MASK (3 << 30)
+#define IO_DPD_REQ_CODE_IDLE (0U << 30)
+#define IO_DPD_REQ_CODE_OFF (1U << 30)
+#define IO_DPD_REQ_CODE_ON (2U << 30)
+#define IO_DPD_REQ_CODE_MASK (3U << 30)
#define IO_DPD_STATUS 0x1bc
#define IO_DPD2_REQ 0x1c0
@@ -101,16 +105,16 @@
#define SEL_DPD_TIM 0x1c8
#define PMC_SCRATCH54 0x258
-#define PMC_SCRATCH54_DATA_SHIFT 8
-#define PMC_SCRATCH54_ADDR_SHIFT 0
+#define PMC_SCRATCH54_DATA_SHIFT 8
+#define PMC_SCRATCH54_ADDR_SHIFT 0
#define PMC_SCRATCH55 0x25c
-#define PMC_SCRATCH55_RESET_TEGRA (1 << 31)
-#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
-#define PMC_SCRATCH55_PINMUX_SHIFT 24
-#define PMC_SCRATCH55_16BITOP (1 << 15)
-#define PMC_SCRATCH55_CHECKSUM_SHIFT 16
-#define PMC_SCRATCH55_I2CSLV1_SHIFT 0
+#define PMC_SCRATCH55_RESET_TEGRA BIT(31)
+#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
+#define PMC_SCRATCH55_PINMUX_SHIFT 24
+#define PMC_SCRATCH55_16BITOP BIT(15)
+#define PMC_SCRATCH55_CHECKSUM_SHIFT 16
+#define PMC_SCRATCH55_I2CSLV1_SHIFT 0
#define GPU_RG_CNTRL 0x2d4
@@ -124,6 +128,12 @@ struct tegra_powergate {
unsigned int num_resets;
};
+struct tegra_io_pad_soc {
+ enum tegra_io_pad id;
+ unsigned int dpd;
+ unsigned int voltage;
+};
+
struct tegra_pmc_soc {
unsigned int num_powergates;
const char *const *powergates;
@@ -132,6 +142,9 @@ struct tegra_pmc_soc {
bool has_tsense_reset;
bool has_gpu_clamps;
+
+ const struct tegra_io_pad_soc *io_pads;
+ unsigned int num_io_pads;
};
/**
@@ -238,8 +251,6 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
return i;
}
- dev_err(pmc->dev, "powergate %s not found\n", name);
-
return -ENODEV;
}
@@ -456,13 +467,12 @@ disable_clks:
static int tegra_genpd_power_on(struct generic_pm_domain *domain)
{
struct tegra_powergate *pg = to_powergate(domain);
- struct tegra_pmc *pmc = pg->pmc;
int err;
err = tegra_powergate_power_up(pg, true);
if (err)
- dev_err(pmc->dev, "failed to turn on PM domain %s: %d\n",
- pg->genpd.name, err);
+ pr_err("failed to turn on PM domain %s: %d\n", pg->genpd.name,
+ err);
return err;
}
@@ -470,13 +480,12 @@ static int tegra_genpd_power_on(struct generic_pm_domain *domain)
static int tegra_genpd_power_off(struct generic_pm_domain *domain)
{
struct tegra_powergate *pg = to_powergate(domain);
- struct tegra_pmc *pmc = pg->pmc;
int err;
err = tegra_powergate_power_down(pg);
if (err)
- dev_err(pmc->dev, "failed to turn off PM domain %s: %d\n",
- pg->genpd.name, err);
+ pr_err("failed to turn off PM domain %s: %d\n",
+ pg->genpd.name, err);
return err;
}
@@ -801,8 +810,7 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
id = tegra_powergate_lookup(pmc, np->name);
if (id < 0) {
- dev_err(pmc->dev, "powergate lookup failed for %s: %d\n",
- np->name, id);
+ pr_err("powergate lookup failed for %s: %d\n", np->name, id);
goto free_mem;
}
@@ -822,20 +830,22 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
err = tegra_powergate_of_get_clks(pg, np);
if (err < 0) {
- dev_err(pmc->dev, "failed to get clocks for %s: %d\n",
- np->name, err);
+ pr_err("failed to get clocks for %s: %d\n", np->name, err);
goto set_available;
}
err = tegra_powergate_of_get_resets(pg, np, off);
if (err < 0) {
- dev_err(pmc->dev, "failed to get resets for %s: %d\n",
- np->name, err);
+ pr_err("failed to get resets for %s: %d\n", np->name, err);
goto remove_clks;
}
- if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS))
- goto power_on_cleanup;
+ if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
+ if (off)
+ WARN_ON(tegra_powergate_power_up(pg, true));
+
+ goto remove_resets;
+ }
/*
* FIXME: If XHCI is enabled for Tegra, then power-up the XUSB
@@ -846,25 +856,33 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
* to be unused.
*/
if (IS_ENABLED(CONFIG_USB_XHCI_TEGRA) &&
- (id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC))
- goto power_on_cleanup;
+ (id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC)) {
+ if (off)
+ WARN_ON(tegra_powergate_power_up(pg, true));
+
+ goto remove_resets;
+ }
- pm_genpd_init(&pg->genpd, NULL, off);
+ err = pm_genpd_init(&pg->genpd, NULL, off);
+ if (err < 0) {
+ pr_err("failed to initialise PM domain %s: %d\n", np->name,
+ err);
+ goto remove_resets;
+ }
err = of_genpd_add_provider_simple(np, &pg->genpd);
if (err < 0) {
- dev_err(pmc->dev, "failed to add genpd provider for %s: %d\n",
- np->name, err);
- goto remove_resets;
+ pr_err("failed to add PM domain provider for %s: %d\n",
+ np->name, err);
+ goto remove_genpd;
}
- dev_dbg(pmc->dev, "added power domain %s\n", pg->genpd.name);
+ pr_debug("added PM domain %s\n", pg->genpd.name);
return;
-power_on_cleanup:
- if (off)
- WARN_ON(tegra_powergate_power_up(pg, true));
+remove_genpd:
+ pm_genpd_remove(&pg->genpd);
remove_resets:
while (pg->num_resets--)
@@ -908,21 +926,36 @@ static void tegra_powergate_init(struct tegra_pmc *pmc,
of_node_put(np);
}
-static int tegra_io_rail_prepare(unsigned int id, unsigned long *request,
- unsigned long *status, unsigned int *bit)
+static const struct tegra_io_pad_soc *
+tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
{
+ unsigned int i;
+
+ for (i = 0; i < pmc->soc->num_io_pads; i++)
+ if (pmc->soc->io_pads[i].id == id)
+ return &pmc->soc->io_pads[i];
+
+ return NULL;
+}
+
+static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
+ unsigned long *status, u32 *mask)
+{
+ const struct tegra_io_pad_soc *pad;
unsigned long rate, value;
- *bit = id % 32;
+ pad = tegra_io_pad_find(pmc, id);
+ if (!pad) {
+ pr_err("invalid I/O pad ID %u\n", id);
+ return -ENOENT;
+ }
- /*
- * There are two sets of 30 bits to select IO rails, but bits 30 and
- * 31 are control bits rather than IO rail selection bits.
- */
- if (id > 63 || *bit == 30 || *bit == 31)
- return -EINVAL;
+ if (pad->dpd == UINT_MAX)
+ return -ENOTSUPP;
- if (id < 32) {
+ *mask = BIT(pad->dpd % 32);
+
+ if (pad->dpd < 32) {
*status = IO_DPD_STATUS;
*request = IO_DPD_REQ;
} else {
@@ -931,6 +964,10 @@ static int tegra_io_rail_prepare(unsigned int id, unsigned long *request,
}
rate = clk_get_rate(pmc->clk);
+ if (!rate) {
+ pr_err("failed to get clock rate\n");
+ return -ENODEV;
+ }
tegra_pmc_writel(DPD_SAMPLE_ENABLE, DPD_SAMPLE);
@@ -942,10 +979,10 @@ static int tegra_io_rail_prepare(unsigned int id, unsigned long *request,
return 0;
}
-static int tegra_io_rail_poll(unsigned long offset, unsigned long mask,
- unsigned long val, unsigned long timeout)
+static int tegra_io_pad_poll(unsigned long offset, u32 mask,
+ u32 val, unsigned long timeout)
{
- unsigned long value;
+ u32 value;
timeout = jiffies + msecs_to_jiffies(timeout);
@@ -960,67 +997,164 @@ static int tegra_io_rail_poll(unsigned long offset, unsigned long mask,
return -ETIMEDOUT;
}
-static void tegra_io_rail_unprepare(void)
+static void tegra_io_pad_unprepare(void)
{
tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
}
-int tegra_io_rail_power_on(unsigned int id)
+/**
+ * tegra_io_pad_power_enable() - enable power to I/O pad
+ * @id: Tegra I/O pad ID for which to enable power
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int tegra_io_pad_power_enable(enum tegra_io_pad id)
{
unsigned long request, status;
- unsigned int bit;
+ u32 mask;
int err;
mutex_lock(&pmc->powergates_lock);
- err = tegra_io_rail_prepare(id, &request, &status, &bit);
- if (err)
- goto error;
+ err = tegra_io_pad_prepare(id, &request, &status, &mask);
+ if (err < 0) {
+ pr_err("failed to prepare I/O pad: %d\n", err);
+ goto unlock;
+ }
- tegra_pmc_writel(IO_DPD_REQ_CODE_OFF | BIT(bit), request);
+ tegra_pmc_writel(IO_DPD_REQ_CODE_OFF | mask, request);
- err = tegra_io_rail_poll(status, BIT(bit), 0, 250);
- if (err) {
- pr_info("tegra_io_rail_poll() failed: %d\n", err);
- goto error;
+ err = tegra_io_pad_poll(status, mask, 0, 250);
+ if (err < 0) {
+ pr_err("failed to enable I/O pad: %d\n", err);
+ goto unlock;
}
- tegra_io_rail_unprepare();
+ tegra_io_pad_unprepare();
-error:
+unlock:
mutex_unlock(&pmc->powergates_lock);
-
return err;
}
-EXPORT_SYMBOL(tegra_io_rail_power_on);
+EXPORT_SYMBOL(tegra_io_pad_power_enable);
-int tegra_io_rail_power_off(unsigned int id)
+/**
+ * tegra_io_pad_power_disable() - disable power to I/O pad
+ * @id: Tegra I/O pad ID for which to disable power
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int tegra_io_pad_power_disable(enum tegra_io_pad id)
{
unsigned long request, status;
- unsigned int bit;
+ u32 mask;
int err;
mutex_lock(&pmc->powergates_lock);
- err = tegra_io_rail_prepare(id, &request, &status, &bit);
- if (err) {
- pr_info("tegra_io_rail_prepare() failed: %d\n", err);
- goto error;
+ err = tegra_io_pad_prepare(id, &request, &status, &mask);
+ if (err < 0) {
+ pr_err("failed to prepare I/O pad: %d\n", err);
+ goto unlock;
}
- tegra_pmc_writel(IO_DPD_REQ_CODE_ON | BIT(bit), request);
+ tegra_pmc_writel(IO_DPD_REQ_CODE_ON | mask, request);
- err = tegra_io_rail_poll(status, BIT(bit), BIT(bit), 250);
- if (err)
- goto error;
+ err = tegra_io_pad_poll(status, mask, mask, 250);
+ if (err < 0) {
+ pr_err("failed to disable I/O pad: %d\n", err);
+ goto unlock;
+ }
- tegra_io_rail_unprepare();
+ tegra_io_pad_unprepare();
-error:
+unlock:
mutex_unlock(&pmc->powergates_lock);
-
return err;
}
+EXPORT_SYMBOL(tegra_io_pad_power_disable);
+
+int tegra_io_pad_set_voltage(enum tegra_io_pad id,
+ enum tegra_io_pad_voltage voltage)
+{
+ const struct tegra_io_pad_soc *pad;
+ u32 value;
+
+ pad = tegra_io_pad_find(pmc, id);
+ if (!pad)
+ return -ENOENT;
+
+ if (pad->voltage == UINT_MAX)
+ return -ENOTSUPP;
+
+ mutex_lock(&pmc->powergates_lock);
+
+ /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
+ value = tegra_pmc_readl(PMC_PWR_DET);
+ value |= BIT(pad->voltage);
+ tegra_pmc_writel(value, PMC_PWR_DET);
+
+ /* update I/O voltage */
+ value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+
+ if (voltage == TEGRA_IO_PAD_1800000UV)
+ value &= ~BIT(pad->voltage);
+ else
+ value |= BIT(pad->voltage);
+
+ tegra_pmc_writel(value, PMC_PWR_DET_VALUE);
+
+ mutex_unlock(&pmc->powergates_lock);
+
+ usleep_range(100, 250);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_io_pad_set_voltage);
+
+int tegra_io_pad_get_voltage(enum tegra_io_pad id)
+{
+ const struct tegra_io_pad_soc *pad;
+ u32 value;
+
+ pad = tegra_io_pad_find(pmc, id);
+ if (!pad)
+ return -ENOENT;
+
+ if (pad->voltage == UINT_MAX)
+ return -ENOTSUPP;
+
+ value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+
+ if ((value & BIT(pad->voltage)) == 0)
+ return TEGRA_IO_PAD_1800000UV;
+
+ return TEGRA_IO_PAD_3300000UV;
+}
+EXPORT_SYMBOL(tegra_io_pad_get_voltage);
+
+/**
+ * tegra_io_rail_power_on() - enable power to I/O rail
+ * @id: Tegra I/O pad ID for which to enable power
+ *
+ * See also: tegra_io_pad_power_enable()
+ */
+int tegra_io_rail_power_on(unsigned int id)
+{
+ return tegra_io_pad_power_enable(id);
+}
+EXPORT_SYMBOL(tegra_io_rail_power_on);
+
+/**
+ * tegra_io_rail_power_off() - disable power to I/O rail
+ * @id: Tegra I/O pad ID for which to disable power
+ *
+ * See also: tegra_io_pad_power_disable()
+ */
+int tegra_io_rail_power_off(unsigned int id)
+{
+ return tegra_io_pad_power_disable(id);
+}
EXPORT_SYMBOL(tegra_io_rail_power_off);
#ifdef CONFIG_PM_SLEEP
@@ -1454,6 +1588,39 @@ static const u8 tegra124_cpu_powergates[] = {
TEGRA_POWERGATE_CPU3,
};
+static const struct tegra_io_pad_soc tegra124_io_pads[] = {
+ { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_BB, .dpd = 15, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_COMP, .dpd = 22, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_HV, .dpd = 38, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_NAND, .dpd = 13, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 35, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_SYS_DDC, .dpd = 58, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
+};
+
static const struct tegra_pmc_soc tegra124_pmc_soc = {
.num_powergates = ARRAY_SIZE(tegra124_powergates),
.powergates = tegra124_powergates,
@@ -1461,6 +1628,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.cpu_powergates = tegra124_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = true,
+ .num_io_pads = ARRAY_SIZE(tegra124_io_pads),
+ .io_pads = tegra124_io_pads,
};
static const char * const tegra210_powergates[] = {
@@ -1497,6 +1666,47 @@ static const u8 tegra210_cpu_powergates[] = {
TEGRA_POWERGATE_CPU3,
};
+static const struct tegra_io_pad_soc tegra210_io_pads[] = {
+ { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = 5 },
+ { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 18 },
+ { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = 10 },
+ { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIC, .dpd = 42, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSID, .dpd = 43, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_CSIF, .dpd = 45, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = 19 },
+ { .id = TEGRA_IO_PAD_DEBUG_NONAO, .dpd = 26, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DMIC, .dpd = 50, .voltage = 20 },
+ { .id = TEGRA_IO_PAD_DP, .dpd = 51, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_EMMC, .dpd = 35, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_EMMC2, .dpd = 37, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_GPIO, .dpd = 27, .voltage = 21 },
+ { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = UINT_MAX, .voltage = 11 },
+ { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = 12 },
+ { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = 13 },
+ { .id = TEGRA_IO_PAD_SPI, .dpd = 46, .voltage = 22 },
+ { .id = TEGRA_IO_PAD_SPI_HV, .dpd = 47, .voltage = 23 },
+ { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = 2 },
+ { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB3, .dpd = 18, .voltage = UINT_MAX },
+ { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
+};
+
static const struct tegra_pmc_soc tegra210_pmc_soc = {
.num_powergates = ARRAY_SIZE(tegra210_powergates),
.powergates = tegra210_powergates,
@@ -1504,6 +1714,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.cpu_powergates = tegra210_cpu_powergates,
.has_tsense_reset = true,
.has_gpu_clamps = true,
+ .num_io_pads = ARRAY_SIZE(tegra210_io_pads),
+ .io_pads = tegra210_io_pads,
};
static const struct of_device_id tegra_pmc_match[] = {
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index b73e3534f67b..eacad57f2977 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -1228,7 +1228,7 @@ static int knav_setup_queue_range(struct knav_device *kdev,
range->num_irqs++;
- if (oirq.args_count == 3)
+ if (IS_ENABLED(CONFIG_SMP) && oirq.args_count == 3)
range->irqs[i].cpu_map =
(oirq.args[2] & 0x0000ff00) >> 8;
}
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 3c09e94cf827..28dfdce4beae 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -341,27 +341,20 @@ static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable)
static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
{
struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
- dma_filter_fn filter = sdd->cntrlr_info->filter;
struct device *dev = &sdd->pdev->dev;
- dma_cap_mask_t mask;
if (is_polling(sdd))
return 0;
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
/* Acquire DMA channels */
- sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter,
- sdd->cntrlr_info->dma_rx, dev, "rx");
+ sdd->rx_dma.ch = dma_request_slave_channel(dev, "rx");
if (!sdd->rx_dma.ch) {
dev_err(dev, "Failed to get RX DMA channel\n");
return -EBUSY;
}
spi->dma_rx = sdd->rx_dma.ch;
- sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter,
- sdd->cntrlr_info->dma_tx, dev, "tx");
+ sdd->tx_dma.ch = dma_request_slave_channel(dev, "tx");
if (!sdd->tx_dma.ch) {
dev_err(dev, "Failed to get TX DMA channel\n");
dma_release_channel(sdd->rx_dma.ch);
@@ -1091,11 +1084,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
sdd->cur_bpw = 8;
- if (!sdd->pdev->dev.of_node && (!sci->dma_tx || !sci->dma_rx)) {
- dev_warn(&pdev->dev, "Unable to get SPI tx/rx DMA data. Switching to poll mode\n");
- sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL;
- }
-
sdd->tx_dma.direction = DMA_MEM_TO_DEV;
sdd->rx_dma.direction = DMA_DEV_TO_MEM;
@@ -1205,9 +1193,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n",
sdd->port_id, master->num_chipselect);
- dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\tDMA=[Rx-%p, Tx-%p]\n",
- mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1,
- sci->dma_rx, sci->dma_tx);
+ dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
+ mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
index f607946fd996..58cbb30a9401 100644
--- a/drivers/tty/serial/8250/8250_lpss.c
+++ b/drivers/tty/serial/8250/8250_lpss.c
@@ -157,12 +157,12 @@ static int byt_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
static const struct dw_dma_platform_data qrk_serial_dma_pdata = {
.nr_channels = 2,
.is_private = true,
- .is_nollp = true,
.chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
.chan_priority = CHAN_PRIORITY_ASCENDING,
.block_size = 4095,
.nr_masters = 1,
.data_width = {4},
+ .multi_block = {0},
};
static void qrk_serial_setup_dma(struct lpss8250 *lpss, struct uart_port *port)
diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c
index 940304c33224..02260cfdedb1 100644
--- a/drivers/usb/host/uhci-pci.c
+++ b/drivers/usb/host/uhci-pci.c
@@ -129,6 +129,10 @@ static int uhci_pci_init(struct usb_hcd *hcd)
if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP)
uhci->wait_for_hp = 1;
+ /* Intel controllers use non-PME wakeup signalling */
+ if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
+ device_set_run_wake(uhci_dev(uhci), 1);
+
/* Set up pointers to PCI-specific functions */
uhci->reset_hc = uhci_pci_reset_hc;
uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc;
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index e4220ca8ca27..330a57024cbc 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -31,8 +31,6 @@
#include "vfio_pci_private.h"
-#define PCI_CFG_SPACE_SIZE 256
-
/* Fake capability ID for standard config space */
#define PCI_CAP_ID_BASIC 0
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index e1d39a1e9628..8965e3f536c3 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/clk.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -155,12 +156,27 @@ static struct miscdevice sa1100dog_miscdev = {
};
static int margin __initdata = 60; /* (secs) Default is 1 minute */
+static struct clk *clk;
static int __init sa1100dog_init(void)
{
int ret;
- oscr_freq = get_clock_tick_rate();
+ clk = clk_get(NULL, "OSTIMER0");
+ if (IS_ERR(clk)) {
+ pr_err("SA1100/PXA2xx Watchdog Timer: clock not found: %d\n",
+ (int) PTR_ERR(clk));
+ return PTR_ERR(clk);
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ pr_err("SA1100/PXA2xx Watchdog Timer: clock failed to prepare+enable: %d\n",
+ ret);
+ goto err;
+ }
+
+ oscr_freq = clk_get_rate(clk);
/*
* Read the reset status, and save it for later. If
@@ -176,11 +192,17 @@ static int __init sa1100dog_init(void)
pr_info("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
margin);
return ret;
+err:
+ clk_disable_unprepare(clk);
+ clk_put(clk);
+ return ret;
}
static void __exit sa1100dog_exit(void)
{
misc_deregister(&sa1100dog_miscdev);
+ clk_disable_unprepare(clk);
+ clk_put(clk);
}
module_init(sa1100dog_init);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 86aa79859d4d..aeae8c063451 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -554,7 +554,7 @@ static inline int dio_bio_reap(struct dio *dio, struct dio_submit *sdio)
* filesystems that don't need it and also allows us to create the workqueue
* late enough so the we can include s_id in the name of the workqueue.
*/
-static int sb_init_dio_done_wq(struct super_block *sb)
+int sb_init_dio_done_wq(struct super_block *sb)
{
struct workqueue_struct *old;
struct workqueue_struct *wq = alloc_workqueue("dio/%s",
diff --git a/fs/internal.h b/fs/internal.h
index f4da3341b4a3..4fcf51766d4a 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -184,3 +184,6 @@ typedef loff_t (*iomap_actor_t)(struct inode *inode, loff_t pos, loff_t len,
loff_t iomap_apply(struct inode *inode, loff_t pos, loff_t length,
unsigned flags, struct iomap_ops *ops, void *data,
iomap_actor_t actor);
+
+/* direct-io.c: */
+int sb_init_dio_done_wq(struct super_block *sb);
diff --git a/fs/iomap.c b/fs/iomap.c
index 13dd413b2b9c..354a123f170e 100644
--- a/fs/iomap.c
+++ b/fs/iomap.c
@@ -24,6 +24,7 @@
#include <linux/uio.h>
#include <linux/backing-dev.h>
#include <linux/buffer_head.h>
+#include <linux/task_io_accounting_ops.h>
#include <linux/dax.h>
#include "internal.h"
@@ -584,3 +585,375 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
return 0;
}
EXPORT_SYMBOL_GPL(iomap_fiemap);
+
+/*
+ * Private flags for iomap_dio, must not overlap with the public ones in
+ * iomap.h:
+ */
+#define IOMAP_DIO_WRITE (1 << 30)
+#define IOMAP_DIO_DIRTY (1 << 31)
+
+struct iomap_dio {
+ struct kiocb *iocb;
+ iomap_dio_end_io_t *end_io;
+ loff_t i_size;
+ loff_t size;
+ atomic_t ref;
+ unsigned flags;
+ int error;
+
+ union {
+ /* used during submission and for synchronous completion: */
+ struct {
+ struct iov_iter *iter;
+ struct task_struct *waiter;
+ struct request_queue *last_queue;
+ blk_qc_t cookie;
+ } submit;
+
+ /* used for aio completion: */
+ struct {
+ struct work_struct work;
+ } aio;
+ };
+};
+
+static ssize_t iomap_dio_complete(struct iomap_dio *dio)
+{
+ struct kiocb *iocb = dio->iocb;
+ ssize_t ret;
+
+ if (dio->end_io) {
+ ret = dio->end_io(iocb,
+ dio->error ? dio->error : dio->size,
+ dio->flags);
+ } else {
+ ret = dio->error;
+ }
+
+ if (likely(!ret)) {
+ ret = dio->size;
+ /* check for short read */
+ if (iocb->ki_pos + ret > dio->i_size &&
+ !(dio->flags & IOMAP_DIO_WRITE))
+ ret = dio->i_size - iocb->ki_pos;
+ iocb->ki_pos += ret;
+ }
+
+ inode_dio_end(file_inode(iocb->ki_filp));
+ kfree(dio);
+
+ return ret;
+}
+
+static void iomap_dio_complete_work(struct work_struct *work)
+{
+ struct iomap_dio *dio = container_of(work, struct iomap_dio, aio.work);
+ struct kiocb *iocb = dio->iocb;
+ bool is_write = (dio->flags & IOMAP_DIO_WRITE);
+ ssize_t ret;
+
+ ret = iomap_dio_complete(dio);
+ if (is_write && ret > 0)
+ ret = generic_write_sync(iocb, ret);
+ iocb->ki_complete(iocb, ret, 0);
+}
+
+/*
+ * Set an error in the dio if none is set yet. We have to use cmpxchg
+ * as the submission context and the completion context(s) can race to
+ * update the error.
+ */
+static inline void iomap_dio_set_error(struct iomap_dio *dio, int ret)
+{
+ cmpxchg(&dio->error, 0, ret);
+}
+
+static void iomap_dio_bio_end_io(struct bio *bio)
+{
+ struct iomap_dio *dio = bio->bi_private;
+ bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY);
+
+ if (bio->bi_error)
+ iomap_dio_set_error(dio, bio->bi_error);
+
+ if (atomic_dec_and_test(&dio->ref)) {
+ if (is_sync_kiocb(dio->iocb)) {
+ struct task_struct *waiter = dio->submit.waiter;
+
+ WRITE_ONCE(dio->submit.waiter, NULL);
+ wake_up_process(waiter);
+ } else if (dio->flags & IOMAP_DIO_WRITE) {
+ struct inode *inode = file_inode(dio->iocb->ki_filp);
+
+ INIT_WORK(&dio->aio.work, iomap_dio_complete_work);
+ queue_work(inode->i_sb->s_dio_done_wq, &dio->aio.work);
+ } else {
+ iomap_dio_complete_work(&dio->aio.work);
+ }
+ }
+
+ if (should_dirty) {
+ bio_check_pages_dirty(bio);
+ } else {
+ struct bio_vec *bvec;
+ int i;
+
+ bio_for_each_segment_all(bvec, bio, i)
+ put_page(bvec->bv_page);
+ bio_put(bio);
+ }
+}
+
+static blk_qc_t
+iomap_dio_zero(struct iomap_dio *dio, struct iomap *iomap, loff_t pos,
+ unsigned len)
+{
+ struct page *page = ZERO_PAGE(0);
+ struct bio *bio;
+
+ bio = bio_alloc(GFP_KERNEL, 1);
+ bio->bi_bdev = iomap->bdev;
+ bio->bi_iter.bi_sector =
+ iomap->blkno + ((pos - iomap->offset) >> 9);
+ bio->bi_private = dio;
+ bio->bi_end_io = iomap_dio_bio_end_io;
+
+ get_page(page);
+ if (bio_add_page(bio, page, len, 0) != len)
+ BUG();
+ bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC | REQ_IDLE);
+
+ atomic_inc(&dio->ref);
+ return submit_bio(bio);
+}
+
+static loff_t
+iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
+ void *data, struct iomap *iomap)
+{
+ struct iomap_dio *dio = data;
+ unsigned blkbits = blksize_bits(bdev_logical_block_size(iomap->bdev));
+ unsigned fs_block_size = (1 << inode->i_blkbits), pad;
+ unsigned align = iov_iter_alignment(dio->submit.iter);
+ struct iov_iter iter;
+ struct bio *bio;
+ bool need_zeroout = false;
+ int nr_pages, ret;
+
+ if ((pos | length | align) & ((1 << blkbits) - 1))
+ return -EINVAL;
+
+ switch (iomap->type) {
+ case IOMAP_HOLE:
+ if (WARN_ON_ONCE(dio->flags & IOMAP_DIO_WRITE))
+ return -EIO;
+ /*FALLTHRU*/
+ case IOMAP_UNWRITTEN:
+ if (!(dio->flags & IOMAP_DIO_WRITE)) {
+ iov_iter_zero(length, dio->submit.iter);
+ dio->size += length;
+ return length;
+ }
+ dio->flags |= IOMAP_DIO_UNWRITTEN;
+ need_zeroout = true;
+ break;
+ case IOMAP_MAPPED:
+ if (iomap->flags & IOMAP_F_SHARED)
+ dio->flags |= IOMAP_DIO_COW;
+ if (iomap->flags & IOMAP_F_NEW)
+ need_zeroout = true;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return -EIO;
+ }
+
+ /*
+ * Operate on a partial iter trimmed to the extent we were called for.
+ * We'll update the iter in the dio once we're done with this extent.
+ */
+ iter = *dio->submit.iter;
+ iov_iter_truncate(&iter, length);
+
+ nr_pages = iov_iter_npages(&iter, BIO_MAX_PAGES);
+ if (nr_pages <= 0)
+ return nr_pages;
+
+ if (need_zeroout) {
+ /* zero out from the start of the block to the write offset */
+ pad = pos & (fs_block_size - 1);
+ if (pad)
+ iomap_dio_zero(dio, iomap, pos - pad, pad);
+ }
+
+ do {
+ if (dio->error)
+ return 0;
+
+ bio = bio_alloc(GFP_KERNEL, nr_pages);
+ bio->bi_bdev = iomap->bdev;
+ bio->bi_iter.bi_sector =
+ iomap->blkno + ((pos - iomap->offset) >> 9);
+ bio->bi_private = dio;
+ bio->bi_end_io = iomap_dio_bio_end_io;
+
+ ret = bio_iov_iter_get_pages(bio, &iter);
+ if (unlikely(ret)) {
+ bio_put(bio);
+ return ret;
+ }
+
+ if (dio->flags & IOMAP_DIO_WRITE) {
+ bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC | REQ_IDLE);
+ task_io_account_write(bio->bi_iter.bi_size);
+ } else {
+ bio_set_op_attrs(bio, REQ_OP_READ, 0);
+ if (dio->flags & IOMAP_DIO_DIRTY)
+ bio_set_pages_dirty(bio);
+ }
+
+ dio->size += bio->bi_iter.bi_size;
+ pos += bio->bi_iter.bi_size;
+
+ nr_pages = iov_iter_npages(&iter, BIO_MAX_PAGES);
+
+ atomic_inc(&dio->ref);
+
+ dio->submit.last_queue = bdev_get_queue(iomap->bdev);
+ dio->submit.cookie = submit_bio(bio);
+ } while (nr_pages);
+
+ if (need_zeroout) {
+ /* zero out from the end of the write to the end of the block */
+ pad = pos & (fs_block_size - 1);
+ if (pad)
+ iomap_dio_zero(dio, iomap, pos, fs_block_size - pad);
+ }
+
+ iov_iter_advance(dio->submit.iter, length);
+ return length;
+}
+
+ssize_t
+iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
+ iomap_dio_end_io_t end_io)
+{
+ struct address_space *mapping = iocb->ki_filp->f_mapping;
+ struct inode *inode = file_inode(iocb->ki_filp);
+ size_t count = iov_iter_count(iter);
+ loff_t pos = iocb->ki_pos, end = iocb->ki_pos + count - 1, ret = 0;
+ unsigned int flags = IOMAP_DIRECT;
+ struct blk_plug plug;
+ struct iomap_dio *dio;
+
+ lockdep_assert_held(&inode->i_rwsem);
+
+ if (!count)
+ return 0;
+
+ dio = kmalloc(sizeof(*dio), GFP_KERNEL);
+ if (!dio)
+ return -ENOMEM;
+
+ dio->iocb = iocb;
+ atomic_set(&dio->ref, 1);
+ dio->size = 0;
+ dio->i_size = i_size_read(inode);
+ dio->end_io = end_io;
+ dio->error = 0;
+ dio->flags = 0;
+
+ dio->submit.iter = iter;
+ if (is_sync_kiocb(iocb)) {
+ dio->submit.waiter = current;
+ dio->submit.cookie = BLK_QC_T_NONE;
+ dio->submit.last_queue = NULL;
+ }
+
+ if (iov_iter_rw(iter) == READ) {
+ if (pos >= dio->i_size)
+ goto out_free_dio;
+
+ if (iter->type == ITER_IOVEC)
+ dio->flags |= IOMAP_DIO_DIRTY;
+ } else {
+ dio->flags |= IOMAP_DIO_WRITE;
+ flags |= IOMAP_WRITE;
+ }
+
+ if (mapping->nrpages) {
+ ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, end);
+ if (ret)
+ goto out_free_dio;
+
+ ret = invalidate_inode_pages2_range(mapping,
+ iocb->ki_pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
+ WARN_ON_ONCE(ret);
+ ret = 0;
+ }
+
+ inode_dio_begin(inode);
+
+ blk_start_plug(&plug);
+ do {
+ ret = iomap_apply(inode, pos, count, flags, ops, dio,
+ iomap_dio_actor);
+ if (ret <= 0) {
+ /* magic error code to fall back to buffered I/O */
+ if (ret == -ENOTBLK)
+ ret = 0;
+ break;
+ }
+ pos += ret;
+ } while ((count = iov_iter_count(iter)) > 0);
+ blk_finish_plug(&plug);
+
+ if (ret < 0)
+ iomap_dio_set_error(dio, ret);
+
+ if (ret >= 0 && iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) &&
+ !inode->i_sb->s_dio_done_wq) {
+ ret = sb_init_dio_done_wq(inode->i_sb);
+ if (ret < 0)
+ iomap_dio_set_error(dio, ret);
+ }
+
+ if (!atomic_dec_and_test(&dio->ref)) {
+ if (!is_sync_kiocb(iocb))
+ return -EIOCBQUEUED;
+
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (!READ_ONCE(dio->submit.waiter))
+ break;
+
+ if (!(iocb->ki_flags & IOCB_HIPRI) ||
+ !dio->submit.last_queue ||
+ !blk_mq_poll(dio->submit.last_queue,
+ dio->submit.cookie))
+ io_schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+ }
+
+ /*
+ * Try again to invalidate clean pages which might have been cached by
+ * non-direct readahead, or faulted in by get_user_pages() if the source
+ * of the write was an mmap'ed region of the file we're writing. Either
+ * one is a pretty crazy thing to do, so we don't support it 100%. If
+ * this invalidation fails, tough, the write still worked...
+ */
+ if (iov_iter_rw(iter) == WRITE && mapping->nrpages) {
+ ret = invalidate_inode_pages2_range(mapping,
+ iocb->ki_pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
+ WARN_ON_ONCE(ret);
+ }
+
+ return iomap_dio_complete(dio);
+
+out_free_dio:
+ kfree(dio);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iomap_dio_rw);
diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
index 38887cc5577f..b5dbc9c6530c 100644
--- a/fs/orangefs/orangefs-debugfs.c
+++ b/fs/orangefs/orangefs-debugfs.c
@@ -671,8 +671,10 @@ int orangefs_prepare_debugfs_help_string(int at_boot)
*/
cdm_element_count =
orangefs_prepare_cdm_array(client_debug_array_string);
- if (cdm_element_count <= 0)
+ if (cdm_element_count <= 0) {
+ kfree(new);
goto out;
+ }
for (i = 0; i < cdm_element_count; i++) {
strlcat(new, "\t", string_size);
diff --git a/fs/orangefs/orangefs-sysfs.c b/fs/orangefs/orangefs-sysfs.c
index a799546a67f7..084954448f18 100644
--- a/fs/orangefs/orangefs-sysfs.c
+++ b/fs/orangefs/orangefs-sysfs.c
@@ -609,15 +609,6 @@ static ssize_t sysfs_service_op_store(struct kobject *kobj,
new_op->upcall.req.param.u.value32[0] = val1;
new_op->upcall.req.param.u.value32[1] = val2;
goto value_set;
- } else if (!strcmp(attr->attr.name,
- "perf_counter_reset")) {
- if ((val > 0)) {
- new_op->upcall.req.param.op =
- ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE;
- } else {
- rc = 0;
- goto out;
- }
}
} else if (!strcmp(kobj->name, ACACHE_KOBJ_ID)) {
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 7ff7712f284e..0a908ae7af13 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -50,3 +50,14 @@ config UBIFS_ATIME_SUPPORT
strictatime is the "heavy", relatime is "lighter", etc.
If unsure, say 'N'
+
+config UBIFS_FS_ENCRYPTION
+ bool "UBIFS Encryption"
+ depends on UBIFS_FS
+ select FS_ENCRYPTION
+ default n
+ help
+ Enable encryption of UBIFS files and directories. This
+ feature is similar to ecryptfs, but it is more memory
+ efficient since it avoids caching the encrypted and
+ decrypted pages in the page cache.
diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index c54a24360f85..6f3251c2bf08 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -5,3 +5,4 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
ubifs-y += misc.o
+ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c
new file mode 100644
index 000000000000..3402720f2b28
--- /dev/null
+++ b/fs/ubifs/crypto.c
@@ -0,0 +1,97 @@
+#include "ubifs.h"
+
+static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len)
+{
+ return ubifs_xattr_get(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+ ctx, len);
+}
+
+static int ubifs_crypt_set_context(struct inode *inode, const void *ctx,
+ size_t len, void *fs_data)
+{
+ return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+ ctx, len, 0);
+}
+
+static bool ubifs_crypt_empty_dir(struct inode *inode)
+{
+ return ubifs_check_dir_empty(inode) == 0;
+}
+
+static unsigned int ubifs_crypt_max_namelen(struct inode *inode)
+{
+ if (S_ISLNK(inode->i_mode))
+ return UBIFS_MAX_INO_DATA;
+ else
+ return UBIFS_MAX_NLEN;
+}
+
+static int ubifs_key_prefix(struct inode *inode, u8 **key)
+{
+ static char prefix[] = "ubifs:";
+
+ *key = prefix;
+
+ return sizeof(prefix) - 1;
+}
+
+int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
+ unsigned int in_len, unsigned int *out_len, int block)
+{
+ struct ubifs_info *c = inode->i_sb->s_fs_info;
+ void *p = &dn->data;
+ struct page *ret;
+ unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE);
+
+ ubifs_assert(pad_len <= *out_len);
+ dn->compr_size = cpu_to_le16(in_len);
+
+ /* pad to full block cipher length */
+ if (pad_len != in_len)
+ memset(p + in_len, 0, pad_len - in_len);
+
+ ret = fscrypt_encrypt_page(inode, virt_to_page(&dn->data), pad_len,
+ offset_in_page(&dn->data), block, GFP_NOFS);
+ if (IS_ERR(ret)) {
+ ubifs_err(c, "fscrypt_encrypt_page failed: %ld", PTR_ERR(ret));
+ return PTR_ERR(ret);
+ }
+ *out_len = pad_len;
+
+ return 0;
+}
+
+int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
+ unsigned int *out_len, int block)
+{
+ struct ubifs_info *c = inode->i_sb->s_fs_info;
+ int err;
+ unsigned int clen = le16_to_cpu(dn->compr_size);
+ unsigned int dlen = *out_len;
+
+ if (clen <= 0 || clen > UBIFS_BLOCK_SIZE || clen > dlen) {
+ ubifs_err(c, "bad compr_size: %i", clen);
+ return -EINVAL;
+ }
+
+ ubifs_assert(dlen <= UBIFS_BLOCK_SIZE);
+ err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen,
+ offset_in_page(&dn->data), block);
+ if (err) {
+ ubifs_err(c, "fscrypt_decrypt_page failed: %i", err);
+ return err;
+ }
+ *out_len = clen;
+
+ return 0;
+}
+
+struct fscrypt_operations ubifs_crypt_operations = {
+ .flags = FS_CFLG_OWN_PAGES,
+ .get_context = ubifs_crypt_get_context,
+ .set_context = ubifs_crypt_set_context,
+ .is_encrypted = __ubifs_crypt_is_encrypted,
+ .empty_dir = ubifs_crypt_empty_dir,
+ .max_namelen = ubifs_crypt_max_namelen,
+ .key_prefix = ubifs_key_prefix,
+};
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 69e287e20732..1e712a364680 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -233,7 +233,7 @@ static void dump_ch(const struct ubifs_ch *ch)
void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
{
const struct ubifs_inode *ui = ubifs_inode(inode);
- struct qstr nm = { .name = NULL };
+ struct fscrypt_name nm = {0};
union ubifs_key key;
struct ubifs_dent_node *dent, *pdent = NULL;
int count = 2;
@@ -289,8 +289,8 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
pr_err("\t%d: %s (%s)\n",
count++, dent->name, get_dent_type(dent->type));
- nm.name = dent->name;
- nm.len = le16_to_cpu(dent->nlen);
+ fname_name(&nm) = dent->name;
+ fname_len(&nm) = le16_to_cpu(dent->nlen);
kfree(pdent);
pdent = dent;
key_read(c, &dent->key, &key);
@@ -1107,7 +1107,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
unsigned int nlink = 2;
union ubifs_key key;
struct ubifs_dent_node *dent, *pdent = NULL;
- struct qstr nm = { .name = NULL };
+ struct fscrypt_name nm = {0};
loff_t size = UBIFS_INO_NODE_SZ;
if (!dbg_is_chk_gen(c))
@@ -1128,9 +1128,9 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
return err;
}
- nm.name = dent->name;
- nm.len = le16_to_cpu(dent->nlen);
- size += CALC_DENT_SIZE(nm.len);
+ fname_name(&nm) = dent->name;
+ fname_len(&nm) = le16_to_cpu(dent->nlen);
+ size += CALC_DENT_SIZE(fname_len(&nm));
if (dent->type == UBIFS_ITYPE_DIR)
nlink += 1;
kfree(pdent);
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index ca16c5d7bab1..1c5331ac9614 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -85,11 +85,26 @@ static int inherit_flags(const struct inode *dir, umode_t mode)
* initializes it. Returns new inode in case of success and an error code in
* case of failure.
*/
-struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
+struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
umode_t mode)
{
+ int err;
struct inode *inode;
struct ubifs_inode *ui;
+ bool encrypted = false;
+
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err) {
+ ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err);
+ return ERR_PTR(err);
+ }
+
+ if (!fscrypt_has_encryption_key(dir))
+ return ERR_PTR(-EPERM);
+
+ encrypted = true;
+ }
inode = new_inode(c->vfs_sb);
ui = ubifs_inode(inode);
@@ -165,18 +180,29 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
*/
ui->creat_sqnum = ++c->max_sqnum;
spin_unlock(&c->cnt_lock);
+
+ if (encrypted) {
+ err = fscrypt_inherit_context(dir, inode, &encrypted, true);
+ if (err) {
+ ubifs_err(c, "fscrypt_inherit_context failed: %i", err);
+ make_bad_inode(inode);
+ iput(inode);
+ return ERR_PTR(err);
+ }
+ }
+
return inode;
}
static int dbg_check_name(const struct ubifs_info *c,
const struct ubifs_dent_node *dent,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
if (!dbg_is_chk_gen(c))
return 0;
- if (le16_to_cpu(dent->nlen) != nm->len)
+ if (le16_to_cpu(dent->nlen) != fname_len(nm))
return -EINVAL;
- if (memcmp(dent->name, nm->name, nm->len))
+ if (memcmp(dent->name, fname_name(nm), fname_len(nm)))
return -EINVAL;
return 0;
}
@@ -189,30 +215,61 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
struct inode *inode = NULL;
struct ubifs_dent_node *dent;
struct ubifs_info *c = dir->i_sb->s_fs_info;
+ struct fscrypt_name nm;
dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
- if (dentry->d_name.len > UBIFS_MAX_NLEN)
- return ERR_PTR(-ENAMETOOLONG);
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+
+ /*
+ * DCACHE_ENCRYPTED_WITH_KEY is set if the dentry is
+ * created while the directory was encrypted and we
+ * have access to the key.
+ */
+ if (fscrypt_has_encryption_key(dir))
+ fscrypt_set_encrypted_dentry(dentry);
+ fscrypt_set_d_op(dentry);
+ if (err && err != -ENOKEY)
+ return ERR_PTR(err);
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
+ if (err)
+ return ERR_PTR(err);
+
+ if (fname_len(&nm) > UBIFS_MAX_NLEN) {
+ err = -ENAMETOOLONG;
+ goto out_fname;
+ }
dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
- if (!dent)
- return ERR_PTR(-ENOMEM);
+ if (!dent) {
+ err = -ENOMEM;
+ goto out_fname;
+ }
- dent_key_init(c, &key, dir->i_ino, &dentry->d_name);
+ if (nm.hash) {
+ ubifs_assert(fname_len(&nm) == 0);
+ ubifs_assert(fname_name(&nm) == NULL);
+ dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
+ err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
+ } else {
+ dent_key_init(c, &key, dir->i_ino, &nm);
+ err = ubifs_tnc_lookup_nm(c, &key, dent, &nm);
+ }
- err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name);
if (err) {
if (err == -ENOENT) {
dbg_gen("not found");
goto done;
}
- goto out;
+ goto out_dent;
}
- if (dbg_check_name(c, dent, &dentry->d_name)) {
+ if (dbg_check_name(c, dent, &nm)) {
err = -EINVAL;
- goto out;
+ goto out_dent;
}
inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum));
@@ -225,11 +282,12 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
ubifs_err(c, "dead directory entry '%pd', error %d",
dentry, err);
ubifs_ro_mode(c, err);
- goto out;
+ goto out_dent;
}
done:
kfree(dent);
+ fscrypt_free_filename(&nm);
/*
* Note, d_splice_alias() would be required instead if we supported
* NFS.
@@ -237,8 +295,10 @@ done:
d_add(dentry, inode);
return NULL;
-out:
+out_dent:
kfree(dent);
+out_fname:
+ fscrypt_free_filename(&nm);
return ERR_PTR(err);
}
@@ -247,10 +307,11 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
{
struct inode *inode;
struct ubifs_info *c = dir->i_sb->s_fs_info;
- int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
.dirtied_ino = 1 };
struct ubifs_inode *dir_ui = ubifs_inode(dir);
+ struct fscrypt_name nm;
+ int err, sz_change;
/*
* Budget request settings: new inode, new direntry, changing the
@@ -264,10 +325,16 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
if (err)
return err;
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+ if (err)
+ goto out_budg;
+
+ sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
inode = ubifs_new_inode(c, dir, mode);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
- goto out_budg;
+ goto out_fname;
}
err = ubifs_init_security(dir, inode, &dentry->d_name);
@@ -278,12 +345,13 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
dir->i_size += sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
if (err)
goto out_cancel;
mutex_unlock(&dir_ui->ui_mutex);
ubifs_release_budget(c, &req);
+ fscrypt_free_filename(&nm);
insert_inode_hash(inode);
d_instantiate(dentry, inode);
return 0;
@@ -295,6 +363,8 @@ out_cancel:
out_inode:
make_bad_inode(inode);
iput(inode);
+out_fname:
+ fscrypt_free_filename(&nm);
out_budg:
ubifs_release_budget(c, &req);
ubifs_err(c, "cannot create regular file, error %d", err);
@@ -310,6 +380,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
struct ubifs_budget_req ino_req = { .dirtied_ino = 1 };
struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir);
int err, instantiated = 0;
+ struct fscrypt_name nm;
/*
* Budget request settings: new dirty inode, new direntry,
@@ -319,13 +390,30 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
dentry, mode, dir->i_ino);
- err = ubifs_budget_space(c, &req);
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err)
+ return err;
+
+ if (!fscrypt_has_encryption_key(dir)) {
+ return -EPERM;
+ }
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
if (err)
return err;
+ err = ubifs_budget_space(c, &req);
+ if (err) {
+ fscrypt_free_filename(&nm);
+ return err;
+ }
+
err = ubifs_budget_space(c, &ino_req);
if (err) {
ubifs_release_budget(c, &req);
+ fscrypt_free_filename(&nm);
return err;
}
@@ -361,7 +449,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
mutex_unlock(&ui->ui_mutex);
mutex_lock(&dir_ui->ui_mutex);
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
if (err)
goto out_cancel;
mutex_unlock(&dir_ui->ui_mutex);
@@ -380,6 +468,7 @@ out_budg:
ubifs_release_budget(c, &req);
if (!instantiated)
ubifs_release_budget(c, &ino_req);
+ fscrypt_free_filename(&nm);
ubifs_err(c, "cannot create temporary file, error %d", err);
return err;
}
@@ -439,12 +528,14 @@ static unsigned int vfs_dent_type(uint8_t type)
*/
static int ubifs_readdir(struct file *file, struct dir_context *ctx)
{
- int err = 0;
- struct qstr nm;
+ int fstr_real_len = 0, err = 0;
+ struct fscrypt_name nm;
+ struct fscrypt_str fstr = {0};
union ubifs_key key;
struct ubifs_dent_node *dent;
struct inode *dir = file_inode(file);
struct ubifs_info *c = dir->i_sb->s_fs_info;
+ bool encrypted = ubifs_crypt_is_encrypted(dir);
dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos);
@@ -455,6 +546,18 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
*/
return 0;
+ if (encrypted) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err && err != -ENOKEY)
+ return err;
+
+ err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr);
+ if (err)
+ return err;
+
+ fstr_real_len = fstr.len;
+ }
+
if (file->f_version == 0) {
/*
* The file was seek'ed, which means that @file->private_data
@@ -476,12 +579,15 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
/* File positions 0 and 1 correspond to "." and ".." */
if (ctx->pos < 2) {
ubifs_assert(!file->private_data);
- if (!dir_emit_dots(file, ctx))
+ if (!dir_emit_dots(file, ctx)) {
+ if (encrypted)
+ fscrypt_fname_free_buffer(&fstr);
return 0;
+ }
/* Find the first entry in TNC and save it */
lowest_dent_key(c, &key, dir->i_ino);
- nm.name = NULL;
+ fname_len(&nm) = 0;
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
err = PTR_ERR(dent);
@@ -499,7 +605,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
* Find the entry corresponding to @ctx->pos or the closest one.
*/
dent_key_init_hash(c, &key, dir->i_ino, ctx->pos);
- nm.name = NULL;
+ fname_len(&nm) = 0;
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
err = PTR_ERR(dent);
@@ -516,15 +622,33 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
ubifs_inode(dir)->creat_sqnum);
- nm.len = le16_to_cpu(dent->nlen);
- if (!dir_emit(ctx, dent->name, nm.len,
+ fname_len(&nm) = le16_to_cpu(dent->nlen);
+ fname_name(&nm) = dent->name;
+
+ if (encrypted) {
+ fstr.len = fstr_real_len;
+
+ err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c,
+ &dent->key),
+ le32_to_cpu(dent->cookie),
+ &nm.disk_name, &fstr);
+ if (err)
+ goto out;
+ } else {
+ fstr.len = fname_len(&nm);
+ fstr.name = fname_name(&nm);
+ }
+
+ if (!dir_emit(ctx, fstr.name, fstr.len,
le64_to_cpu(dent->inum),
- vfs_dent_type(dent->type)))
+ vfs_dent_type(dent->type))) {
+ if (encrypted)
+ fscrypt_fname_free_buffer(&fstr);
return 0;
+ }
/* Switch to the next entry */
key_read(c, &dent->key, &key);
- nm.name = dent->name;
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
err = PTR_ERR(dent);
@@ -541,6 +665,9 @@ out:
kfree(file->private_data);
file->private_data = NULL;
+ if (encrypted)
+ fscrypt_fname_free_buffer(&fstr);
+
if (err != -ENOENT)
ubifs_err(c, "cannot find next direntry, error %d", err);
else
@@ -601,6 +728,7 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2,
.dirtied_ino_d = ALIGN(ui->data_len, 8) };
+ struct fscrypt_name nm;
/*
* Budget request settings: new direntry, changing the target inode,
@@ -613,13 +741,29 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
ubifs_assert(inode_is_locked(dir));
ubifs_assert(inode_is_locked(inode));
- err = dbg_check_synced_i_size(c, inode);
+ if (ubifs_crypt_is_encrypted(dir)) {
+ if (!fscrypt_has_permitted_context(dir, inode))
+ return -EPERM;
+
+ err = fscrypt_get_encryption_info(inode);
+ if (err)
+ return err;
+
+ if (!fscrypt_has_encryption_key(inode))
+ return -EPERM;
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
if (err)
return err;
+ err = dbg_check_synced_i_size(c, inode);
+ if (err)
+ goto out_fname;
+
err = ubifs_budget_space(c, &req);
if (err)
- return err;
+ goto out_fname;
lock_2_inodes(dir, inode);
inc_nlink(inode);
@@ -628,13 +772,14 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
dir->i_size += sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
if (err)
goto out_cancel;
unlock_2_inodes(dir, inode);
ubifs_release_budget(c, &req);
d_instantiate(dentry, inode);
+ fscrypt_free_filename(&nm);
return 0;
out_cancel:
@@ -644,6 +789,8 @@ out_cancel:
unlock_2_inodes(dir, inode);
ubifs_release_budget(c, &req);
iput(inode);
+out_fname:
+ fscrypt_free_filename(&nm);
return err;
}
@@ -652,10 +799,10 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
struct ubifs_info *c = dir->i_sb->s_fs_info;
struct inode *inode = d_inode(dentry);
struct ubifs_inode *dir_ui = ubifs_inode(dir);
- int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
- int err, budgeted = 1;
+ int err, sz_change, budgeted = 1;
struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
unsigned int saved_nlink = inode->i_nlink;
+ struct fscrypt_name nm;
/*
* Budget request settings: deletion direntry, deletion inode (+1 for
@@ -667,16 +814,29 @@ 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);
+
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err && err != -ENOKEY)
+ return err;
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
+ if (err)
+ return err;
+
+ sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
ubifs_assert(inode_is_locked(dir));
ubifs_assert(inode_is_locked(inode));
err = dbg_check_synced_i_size(c, inode);
if (err)
- return err;
+ goto out_fname;
err = ubifs_budget_space(c, &req);
if (err) {
if (err != -ENOSPC)
- return err;
+ goto out_fname;
budgeted = 0;
}
@@ -686,7 +846,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
dir->i_size -= sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
if (err)
goto out_cancel;
unlock_2_inodes(dir, inode);
@@ -698,6 +858,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb();
}
+ fscrypt_free_filename(&nm);
return 0;
out_cancel:
@@ -707,21 +868,23 @@ out_cancel:
unlock_2_inodes(dir, inode);
if (budgeted)
ubifs_release_budget(c, &req);
+out_fname:
+ fscrypt_free_filename(&nm);
return err;
}
/**
* check_dir_empty - check if a directory is empty or not.
- * @c: UBIFS file-system description object
* @dir: VFS inode object of the directory to check
*
* This function checks if directory @dir is empty. Returns zero if the
* directory is empty, %-ENOTEMPTY if it is not, and other negative error codes
* in case of of errors.
*/
-static int check_dir_empty(struct ubifs_info *c, struct inode *dir)
+int ubifs_check_dir_empty(struct inode *dir)
{
- struct qstr nm = { .name = NULL };
+ struct ubifs_info *c = dir->i_sb->s_fs_info;
+ struct fscrypt_name nm = { 0 };
struct ubifs_dent_node *dent;
union ubifs_key key;
int err;
@@ -743,10 +906,10 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
{
struct ubifs_info *c = dir->i_sb->s_fs_info;
struct inode *inode = d_inode(dentry);
- int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
- int err, budgeted = 1;
+ int err, sz_change, budgeted = 1;
struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
+ struct fscrypt_name nm;
/*
* Budget request settings: deletion direntry, deletion inode and
@@ -758,14 +921,26 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ino, dir->i_ino);
ubifs_assert(inode_is_locked(dir));
ubifs_assert(inode_is_locked(inode));
- err = check_dir_empty(c, d_inode(dentry));
+ err = ubifs_check_dir_empty(d_inode(dentry));
if (err)
return err;
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err && err != -ENOKEY)
+ return err;
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
+ if (err)
+ return err;
+
+ sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
err = ubifs_budget_space(c, &req);
if (err) {
if (err != -ENOSPC)
- return err;
+ goto out_fname;
budgeted = 0;
}
@@ -776,7 +951,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
dir->i_size -= sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
if (err)
goto out_cancel;
unlock_2_inodes(dir, inode);
@@ -788,6 +963,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb();
}
+ fscrypt_free_filename(&nm);
return 0;
out_cancel:
@@ -798,6 +974,8 @@ out_cancel:
unlock_2_inodes(dir, inode);
if (budgeted)
ubifs_release_budget(c, &req);
+out_fname:
+ fscrypt_free_filename(&nm);
return err;
}
@@ -806,8 +984,9 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct inode *inode;
struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_info *c = dir->i_sb->s_fs_info;
- int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
+ int err, sz_change;
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 };
+ struct fscrypt_name nm;
/*
* Budget request settings: new inode, new direntry and changing parent
@@ -821,10 +1000,27 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
if (err)
return err;
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err)
+ goto out_budg;
+
+ if (!fscrypt_has_encryption_key(dir)) {
+ err = -EPERM;
+ goto out_budg;
+ }
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+ if (err)
+ goto out_budg;
+
+ sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
inode = ubifs_new_inode(c, dir, S_IFDIR | mode);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
- goto out_budg;
+ goto out_fname;
}
err = ubifs_init_security(dir, inode, &dentry->d_name);
@@ -838,7 +1034,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
dir->i_size += sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
if (err) {
ubifs_err(c, "cannot create directory, error %d", err);
goto out_cancel;
@@ -847,6 +1043,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
ubifs_release_budget(c, &req);
d_instantiate(dentry, inode);
+ fscrypt_free_filename(&nm);
return 0;
out_cancel:
@@ -857,6 +1054,8 @@ out_cancel:
out_inode:
make_bad_inode(inode);
iput(inode);
+out_fname:
+ fscrypt_free_filename(&nm);
out_budg:
ubifs_release_budget(c, &req);
return err;
@@ -870,11 +1069,12 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_info *c = dir->i_sb->s_fs_info;
union ubifs_dev_desc *dev = NULL;
- int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
+ int sz_change;
int err, devlen = 0;
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
.new_ino_d = ALIGN(devlen, 8),
.dirtied_ino = 1 };
+ struct fscrypt_name nm;
/*
* Budget request settings: new inode, new direntry and changing parent
@@ -896,11 +1096,28 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
return err;
}
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err)
+ goto out_budg;
+
+ if (!fscrypt_has_encryption_key(dir)) {
+ err = -EPERM;
+ goto out_budg;
+ }
+ }
+
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+ if (err)
+ goto out_budg;
+
+ sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
inode = ubifs_new_inode(c, dir, mode);
if (IS_ERR(inode)) {
kfree(dev);
err = PTR_ERR(inode);
- goto out_budg;
+ goto out_fname;
}
init_special_inode(inode, inode->i_mode, rdev);
@@ -917,7 +1134,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
dir->i_size += sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
if (err)
goto out_cancel;
mutex_unlock(&dir_ui->ui_mutex);
@@ -925,6 +1142,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
ubifs_release_budget(c, &req);
insert_inode_hash(inode);
d_instantiate(dentry, inode);
+ fscrypt_free_filename(&nm);
return 0;
out_cancel:
@@ -934,6 +1152,8 @@ out_cancel:
out_inode:
make_bad_inode(inode);
iput(inode);
+out_fname:
+ fscrypt_free_filename(&nm);
out_budg:
ubifs_release_budget(c, &req);
return err;
@@ -947,10 +1167,27 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_info *c = dir->i_sb->s_fs_info;
int err, len = strlen(symname);
- int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
+ int sz_change = CALC_DENT_SIZE(len);
+ struct fscrypt_str disk_link = FSTR_INIT((char *)symname, len + 1);
+ struct fscrypt_symlink_data *sd = NULL;
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
.new_ino_d = ALIGN(len, 8),
.dirtied_ino = 1 };
+ struct fscrypt_name nm;
+
+ if (ubifs_crypt_is_encrypted(dir)) {
+ err = fscrypt_get_encryption_info(dir);
+ if (err)
+ goto out_budg;
+
+ if (!fscrypt_has_encryption_key(dir)) {
+ err = -EPERM;
+ goto out_budg;
+ }
+
+ disk_link.len = (fscrypt_fname_encrypted_size(dir, len) +
+ sizeof(struct fscrypt_symlink_data));
+ }
/*
* Budget request settings: new inode, new direntry and changing parent
@@ -960,36 +1197,77 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
dbg_gen("dent '%pd', target '%s' in dir ino %lu", dentry,
symname, dir->i_ino);
- if (len > UBIFS_MAX_INO_DATA)
+ if (disk_link.len > UBIFS_MAX_INO_DATA)
return -ENAMETOOLONG;
err = ubifs_budget_space(c, &req);
if (err)
return err;
+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+ if (err)
+ goto out_budg;
+
inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
- goto out_budg;
+ goto out_fname;
}
ui = ubifs_inode(inode);
- ui->data = kmalloc(len + 1, GFP_NOFS);
+ ui->data = kmalloc(disk_link.len, GFP_NOFS);
if (!ui->data) {
err = -ENOMEM;
goto out_inode;
}
- memcpy(ui->data, symname, len);
- ((char *)ui->data)[len] = '\0';
- inode->i_link = ui->data;
+ if (ubifs_crypt_is_encrypted(dir)) {
+ struct qstr istr = QSTR_INIT(symname, len);
+ struct fscrypt_str ostr;
+
+ sd = kzalloc(disk_link.len, GFP_NOFS);
+ if (!sd) {
+ err = -ENOMEM;
+ goto out_inode;
+ }
+
+ err = fscrypt_get_encryption_info(inode);
+ if (err) {
+ kfree(sd);
+ goto out_inode;
+ }
+
+ if (!fscrypt_has_encryption_key(inode)) {
+ kfree(sd);
+ err = -EPERM;
+ goto out_inode;
+ }
+
+ ostr.name = sd->encrypted_path;
+ ostr.len = disk_link.len;
+
+ err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr);
+ if (err) {
+ kfree(sd);
+ goto out_inode;
+ }
+
+ sd->len = cpu_to_le16(ostr.len);
+ disk_link.name = (char *)sd;
+ } else {
+ inode->i_link = ui->data;
+ }
+
+ memcpy(ui->data, disk_link.name, disk_link.len);
+ ((char *)ui->data)[disk_link.len - 1] = '\0';
+
/*
* The terminating zero byte is not written to the flash media and it
* is put just to make later in-memory string processing simpler. Thus,
* data length is @len, not @len + %1.
*/
- ui->data_len = len;
- inode->i_size = ubifs_inode(inode)->ui_size = len;
+ ui->data_len = disk_link.len - 1;
+ inode->i_size = ubifs_inode(inode)->ui_size = disk_link.len - 1;
err = ubifs_init_security(dir, inode, &dentry->d_name);
if (err)
@@ -999,7 +1277,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
dir->i_size += sz_change;
dir_ui->ui_size = dir->i_size;
dir->i_mtime = dir->i_ctime = inode->i_ctime;
- err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
+ err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
if (err)
goto out_cancel;
mutex_unlock(&dir_ui->ui_mutex);
@@ -1007,6 +1285,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
ubifs_release_budget(c, &req);
insert_inode_hash(inode);
d_instantiate(dentry, inode);
+ fscrypt_free_filename(&nm);
return 0;
out_cancel:
@@ -1016,6 +1295,8 @@ out_cancel:
out_inode:
make_bad_inode(inode);
iput(inode);
+out_fname:
+ fscrypt_free_filename(&nm);
out_budg:
ubifs_release_budget(c, &req);
return err;
@@ -1078,15 +1359,14 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
struct ubifs_inode *whiteout_ui = NULL;
int err, release, sync = 0, move = (new_dir != old_dir);
int is_dir = S_ISDIR(old_inode->i_mode);
- int unlink = !!new_inode;
- int new_sz = CALC_DENT_SIZE(new_dentry->d_name.len);
- int old_sz = CALC_DENT_SIZE(old_dentry->d_name.len);
+ int unlink = !!new_inode, new_sz, old_sz;
struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1,
.dirtied_ino = 3 };
struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
.dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
struct timespec time;
unsigned int uninitialized_var(saved_nlink);
+ struct fscrypt_name old_nm, new_nm;
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
@@ -1107,17 +1387,41 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
if (unlink)
ubifs_assert(inode_is_locked(new_inode));
+ if (old_dir != new_dir) {
+ if (ubifs_crypt_is_encrypted(new_dir) &&
+ !fscrypt_has_permitted_context(new_dir, old_inode))
+ return -EPERM;
+ }
+
if (unlink && is_dir) {
- err = check_dir_empty(c, new_inode);
+ err = ubifs_check_dir_empty(new_inode);
if (err)
return err;
}
- err = ubifs_budget_space(c, &req);
+ err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_nm);
if (err)
return err;
+
+ err = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &new_nm);
+ if (err) {
+ fscrypt_free_filename(&old_nm);
+ return err;
+ }
+
+ new_sz = CALC_DENT_SIZE(fname_len(&new_nm));
+ old_sz = CALC_DENT_SIZE(fname_len(&old_nm));
+
+ err = ubifs_budget_space(c, &req);
+ if (err) {
+ fscrypt_free_filename(&old_nm);
+ fscrypt_free_filename(&new_nm);
+ return err;
+ }
err = ubifs_budget_space(c, &ino_req);
if (err) {
+ fscrypt_free_filename(&old_nm);
+ fscrypt_free_filename(&new_nm);
ubifs_release_budget(c, &req);
return err;
}
@@ -1239,8 +1543,8 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
iput(whiteout);
}
- err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry, whiteout,
- sync);
+ err = ubifs_jnl_rename(c, old_dir, old_inode, &old_nm, new_dir,
+ new_inode, &new_nm, whiteout, sync);
if (err)
goto out_cancel;
@@ -1256,6 +1560,9 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
ubifs_release_budget(c, &ino_req);
if (IS_SYNC(old_inode))
err = old_inode->i_sb->s_op->write_inode(old_inode, NULL);
+
+ fscrypt_free_filename(&old_nm);
+ fscrypt_free_filename(&new_nm);
return err;
out_cancel:
@@ -1284,6 +1591,8 @@ out_cancel:
unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
ubifs_release_budget(c, &ino_req);
ubifs_release_budget(c, &req);
+ fscrypt_free_filename(&old_nm);
+ fscrypt_free_filename(&new_nm);
return err;
}
@@ -1298,9 +1607,27 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *snd_inode = d_inode(new_dentry);
struct timespec time;
int err;
+ struct fscrypt_name fst_nm, snd_nm;
ubifs_assert(fst_inode && snd_inode);
+ if ((ubifs_crypt_is_encrypted(old_dir) ||
+ ubifs_crypt_is_encrypted(new_dir)) &&
+ (old_dir != new_dir) &&
+ (!fscrypt_has_permitted_context(new_dir, fst_inode) ||
+ !fscrypt_has_permitted_context(old_dir, snd_inode)))
+ return -EPERM;
+
+ err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &fst_nm);
+ if (err)
+ return err;
+
+ err = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &snd_nm);
+ if (err) {
+ fscrypt_free_filename(&fst_nm);
+ return err;
+ }
+
lock_4_inodes(old_dir, new_dir, NULL, NULL);
time = ubifs_current_time(old_dir);
@@ -1320,12 +1647,14 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
}
}
- err = ubifs_jnl_xrename(c, old_dir, old_dentry, new_dir, new_dentry,
- sync);
+ err = ubifs_jnl_xrename(c, old_dir, fst_inode, &fst_nm, new_dir,
+ snd_inode, &snd_nm, sync);
unlock_4_inodes(old_dir, new_dir, NULL, NULL);
ubifs_release_budget(c, &req);
+ fscrypt_free_filename(&fst_nm);
+ fscrypt_free_filename(&snd_nm);
return err;
}
@@ -1384,6 +1713,14 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
return 0;
}
+static int ubifs_dir_open(struct inode *dir, struct file *file)
+{
+ if (ubifs_crypt_is_encrypted(dir))
+ return fscrypt_get_encryption_info(dir) ? -EACCES : 0;
+
+ return 0;
+}
+
const struct inode_operations ubifs_dir_inode_operations = {
.lookup = ubifs_lookup,
.create = ubifs_create,
@@ -1410,6 +1747,7 @@ const struct file_operations ubifs_dir_operations = {
.iterate_shared = ubifs_readdir,
.fsync = ubifs_fsync,
.unlocked_ioctl = ubifs_ioctl,
+ .open = ubifs_dir_open,
#ifdef CONFIG_COMPAT
.compat_ioctl = ubifs_compat_ioctl,
#endif
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b4fbeefba246..aa0625f4f642 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -78,6 +78,13 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
goto dump;
dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
+
+ if (ubifs_crypt_is_encrypted(inode)) {
+ err = ubifs_decrypt(inode, dn, &dlen, block);
+ if (err)
+ goto dump;
+ }
+
out_len = UBIFS_BLOCK_SIZE;
err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
le16_to_cpu(dn->compr_type));
@@ -650,6 +657,13 @@ static int populate_page(struct ubifs_info *c, struct page *page,
dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
out_len = UBIFS_BLOCK_SIZE;
+
+ if (ubifs_crypt_is_encrypted(inode)) {
+ err = ubifs_decrypt(inode, dn, &dlen, page_block);
+ if (err)
+ goto out_err;
+ }
+
err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
le16_to_cpu(dn->compr_type));
if (err || len != out_len)
@@ -1594,6 +1608,15 @@ static const struct vm_operations_struct ubifs_file_vm_ops = {
static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
int err;
+ struct inode *inode = file->f_mapping->host;
+
+ if (ubifs_crypt_is_encrypted(inode)) {
+ err = fscrypt_get_encryption_info(inode);
+ if (err)
+ return -EACCES;
+ if (!fscrypt_has_encryption_key(inode))
+ return -ENOKEY;
+ }
err = generic_file_mmap(file, vma);
if (err)
@@ -1605,6 +1628,88 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
+static int ubifs_file_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+ struct dentry *dir;
+ struct ubifs_info *c = inode->i_sb->s_fs_info;
+
+ if (ubifs_crypt_is_encrypted(inode)) {
+ ret = fscrypt_get_encryption_info(inode);
+ if (ret)
+ return -EACCES;
+ if (!fscrypt_has_encryption_key(inode))
+ return -ENOKEY;
+ }
+
+ dir = dget_parent(file_dentry(filp));
+ if (ubifs_crypt_is_encrypted(d_inode(dir)) &&
+ !fscrypt_has_permitted_context(d_inode(dir), inode)) {
+ ubifs_err(c, "Inconsistent encryption contexts: %lu/%lu",
+ (unsigned long) d_inode(dir)->i_ino,
+ (unsigned long) inode->i_ino);
+ dput(dir);
+ ubifs_ro_mode(c, -EPERM);
+ return -EPERM;
+ }
+ dput(dir);
+
+ return 0;
+}
+
+static const char *ubifs_get_link(struct dentry *dentry,
+ struct inode *inode,
+ struct delayed_call *done)
+{
+ int err;
+ struct fscrypt_symlink_data *sd;
+ struct ubifs_inode *ui = ubifs_inode(inode);
+ struct fscrypt_str cstr;
+ struct fscrypt_str pstr;
+
+ if (!ubifs_crypt_is_encrypted(inode))
+ return ui->data;
+
+ if (!dentry)
+ return ERR_PTR(-ECHILD);
+
+ err = fscrypt_get_encryption_info(inode);
+ if (err)
+ return ERR_PTR(err);
+
+ sd = (struct fscrypt_symlink_data *)ui->data;
+ cstr.name = sd->encrypted_path;
+ cstr.len = le16_to_cpu(sd->len);
+
+ if (cstr.len == 0)
+ return ERR_PTR(-ENOENT);
+
+ if ((cstr.len + sizeof(struct fscrypt_symlink_data) - 1) > ui->data_len)
+ return ERR_PTR(-EIO);
+
+ err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
+ if (err)
+ return ERR_PTR(err);
+
+ err = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr);
+ if (err) {
+ fscrypt_fname_free_buffer(&pstr);
+ return ERR_PTR(err);
+ }
+
+ pstr.name[pstr.len] = '\0';
+
+ // XXX this probably won't happen anymore...
+ if (pstr.name[0] == '\0') {
+ fscrypt_fname_free_buffer(&pstr);
+ return ERR_PTR(-ENOENT);
+ }
+
+ set_delayed_call(done, kfree_link, pstr.name);
+ return pstr.name;
+}
+
+
const struct address_space_operations ubifs_file_address_operations = {
.readpage = ubifs_readpage,
.writepage = ubifs_writepage,
@@ -1629,7 +1734,7 @@ const struct inode_operations ubifs_file_inode_operations = {
const struct inode_operations ubifs_symlink_inode_operations = {
.readlink = generic_readlink,
- .get_link = simple_get_link,
+ .get_link = ubifs_get_link,
.setattr = ubifs_setattr,
.getattr = ubifs_getattr,
.listxattr = ubifs_listxattr,
@@ -1647,6 +1752,7 @@ const struct file_operations ubifs_file_operations = {
.unlocked_ioctl = ubifs_ioctl,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
+ .open = ubifs_file_open,
#ifdef CONFIG_COMPAT
.compat_ioctl = ubifs_compat_ioctl,
#endif
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index e845c64b6ce1..7b35e3d6cde7 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -846,10 +846,6 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
*/
while (1) {
lp = ubifs_fast_find_freeable(c);
- if (IS_ERR(lp)) {
- err = PTR_ERR(lp);
- goto out;
- }
if (!lp)
break;
ubifs_assert(!(lp->flags & LPROPS_TAKEN));
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 97be41215332..3be28900bf37 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -452,16 +452,22 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer)
*/
static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf)
{
+ ktime_t softlimit = ms_to_ktime(dirty_writeback_interval * 10);
+ unsigned long long delta = dirty_writeback_interval;
+
+ /* centi to milli, milli to nano, then 10% */
+ delta *= 10ULL * NSEC_PER_MSEC / 10ULL;
+
ubifs_assert(!hrtimer_active(&wbuf->timer));
+ ubifs_assert(delta <= ULONG_MAX);
if (wbuf->no_timer)
return;
dbg_io("set timer for jhead %s, %llu-%llu millisecs",
dbg_jhead(wbuf->jhead),
- div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC),
- div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta,
- USEC_PER_SEC));
- hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta,
+ div_u64(ktime_to_ns(softlimit), USEC_PER_SEC),
+ div_u64(ktime_to_ns(softlimit) + delta, USEC_PER_SEC));
+ hrtimer_start_range_ns(&wbuf->timer, softlimit, delta,
HRTIMER_MODE_REL);
}
@@ -1059,10 +1065,6 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf)
hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
wbuf->timer.function = wbuf_timer_callback_nolock;
- wbuf->softlimit = ktime_set(WBUF_TIMEOUT_SOFTLIMIT, 0);
- wbuf->delta = WBUF_TIMEOUT_HARDLIMIT - WBUF_TIMEOUT_SOFTLIMIT;
- wbuf->delta *= 1000000000ULL;
- ubifs_assert(wbuf->delta <= ULONG_MAX);
return 0;
}
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
index 3c7b29de0ca7..78d713644df3 100644
--- a/fs/ubifs/ioctl.c
+++ b/fs/ubifs/ioctl.c
@@ -181,6 +181,26 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mnt_drop_write_file(file);
return err;
}
+ case FS_IOC_SET_ENCRYPTION_POLICY: {
+#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+ struct ubifs_info *c = inode->i_sb->s_fs_info;
+
+ err = ubifs_enable_encryption(c);
+ if (err)
+ return err;
+
+ return fscrypt_ioctl_set_policy(file, (const void __user *)arg);
+#else
+ return -EOPNOTSUPP;
+#endif
+ }
+ case FS_IOC_GET_ENCRYPTION_POLICY: {
+#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+ return fscrypt_ioctl_get_policy(file, (void __user *)arg);
+#else
+ return -EOPNOTSUPP;
+#endif
+ }
default:
return -ENOTTY;
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 91bc76dc559e..a459211a1c21 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -78,16 +78,6 @@ static inline void zero_ino_node_unused(struct ubifs_ino_node *ino)
static inline void zero_dent_node_unused(struct ubifs_dent_node *dent)
{
dent->padding1 = 0;
- memset(dent->padding2, 0, 4);
-}
-
-/**
- * zero_data_node_unused - zero out unused fields of an on-flash data node.
- * @data: the data node to zero out
- */
-static inline void zero_data_node_unused(struct ubifs_data_node *data)
-{
- memset(data->padding, 0, 2);
}
/**
@@ -511,6 +501,14 @@ static void mark_inode_clean(struct ubifs_info *c, struct ubifs_inode *ui)
ui->dirty = 0;
}
+static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent)
+{
+ if (c->double_hash)
+ dent->cookie = prandom_u32();
+ else
+ dent->cookie = 0;
+}
+
/**
* ubifs_jnl_update - update inode.
* @c: UBIFS file-system description object
@@ -539,7 +537,7 @@ static void mark_inode_clean(struct ubifs_info *c, struct ubifs_inode *ui)
* success. In case of failure, a negative error code is returned.
*/
int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
- const struct qstr *nm, const struct inode *inode,
+ const struct fscrypt_name *nm, const struct inode *inode,
int deletion, int xent)
{
int err, dlen, ilen, len, lnum, ino_offs, dent_offs;
@@ -551,11 +549,11 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
struct ubifs_ino_node *ino;
union ubifs_key dent_key, ino_key;
- dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu",
- inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino);
+ //dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu",
+ // inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino);
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
- dlen = UBIFS_DENT_NODE_SZ + nm->len + 1;
+ dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1;
ilen = UBIFS_INO_NODE_SZ;
/*
@@ -596,9 +594,11 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
key_write(c, &dent_key, dent->key);
dent->inum = deletion ? 0 : cpu_to_le64(inode->i_ino);
dent->type = get_dent_type(inode->i_mode);
- dent->nlen = cpu_to_le16(nm->len);
- memcpy(dent->name, nm->name, nm->len);
- dent->name[nm->len] = '\0';
+ dent->nlen = cpu_to_le16(fname_len(nm));
+ memcpy(dent->name, fname_name(nm), fname_len(nm));
+ dent->name[fname_len(nm)] = '\0';
+ set_dent_cookie(c, dent);
+
zero_dent_node_unused(dent);
ubifs_prep_grp_node(c, dent, dlen, 0);
@@ -697,14 +697,18 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
const union ubifs_key *key, const void *buf, int len)
{
struct ubifs_data_node *data;
- int err, lnum, offs, compr_type, out_len;
+ int err, lnum, offs, compr_type, out_len, compr_len;
int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1;
struct ubifs_inode *ui = ubifs_inode(inode);
+ bool encrypted = ubifs_crypt_is_encrypted(inode);
dbg_jnlk(key, "ino %lu, blk %u, len %d, key ",
(unsigned long)key_inum(c, key), key_block(c, key), len);
ubifs_assert(len <= UBIFS_BLOCK_SIZE);
+ if (encrypted)
+ dlen += UBIFS_CIPHER_BLOCK_SIZE;
+
data = kmalloc(dlen, GFP_NOFS | __GFP_NOWARN);
if (!data) {
/*
@@ -722,7 +726,6 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
data->ch.node_type = UBIFS_DATA_NODE;
key_write(c, key, &data->key);
data->size = cpu_to_le32(len);
- zero_data_node_unused(data);
if (!(ui->flags & UBIFS_COMPR_FL))
/* Compression is disabled for this inode */
@@ -730,9 +733,18 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
else
compr_type = ui->compr_type;
- out_len = dlen - UBIFS_DATA_NODE_SZ;
- ubifs_compress(c, buf, len, &data->data, &out_len, &compr_type);
- ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);
+ out_len = compr_len = dlen - UBIFS_DATA_NODE_SZ;
+ ubifs_compress(c, buf, len, &data->data, &compr_len, &compr_type);
+ ubifs_assert(compr_len <= UBIFS_BLOCK_SIZE);
+
+ if (encrypted) {
+ err = ubifs_encrypt(inode, data, compr_len, &out_len, key_block(c, key));
+ if (err)
+ goto out_free;
+
+ } else {
+ data->compr_size = 0;
+ }
dlen = UBIFS_DATA_NODE_SZ + out_len;
data->compr_type = cpu_to_le16(compr_type);
@@ -911,9 +923,11 @@ int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode)
* ubifs_jnl_xrename - cross rename two directory entries.
* @c: UBIFS file-system description object
* @fst_dir: parent inode of 1st directory entry to exchange
- * @fst_dentry: 1st directory entry to exchange
+ * @fst_inode: 1st inode to exchange
+ * @fst_nm: name of 1st inode to exchange
* @snd_dir: parent inode of 2nd directory entry to exchange
- * @snd_dentry: 2nd directory entry to exchange
+ * @snd_inode: 2nd inode to exchange
+ * @snd_nm: name of 2nd inode to exchange
* @sync: non-zero if the write-buffer has to be synchronized
*
* This function implements the cross rename operation which may involve
@@ -922,29 +936,29 @@ int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode)
* returned.
*/
int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
- const struct dentry *fst_dentry,
+ const struct inode *fst_inode,
+ const struct fscrypt_name *fst_nm,
const struct inode *snd_dir,
- const struct dentry *snd_dentry, int sync)
+ const struct inode *snd_inode,
+ const struct fscrypt_name *snd_nm, int sync)
{
union ubifs_key key;
struct ubifs_dent_node *dent1, *dent2;
int err, dlen1, dlen2, lnum, offs, len, plen = UBIFS_INO_NODE_SZ;
int aligned_dlen1, aligned_dlen2;
int twoparents = (fst_dir != snd_dir);
- const struct inode *fst_inode = d_inode(fst_dentry);
- const struct inode *snd_inode = d_inode(snd_dentry);
void *p;
- dbg_jnl("dent '%pd' in dir ino %lu between dent '%pd' in dir ino %lu",
- fst_dentry, fst_dir->i_ino, snd_dentry, snd_dir->i_ino);
+ //dbg_jnl("dent '%pd' in dir ino %lu between dent '%pd' in dir ino %lu",
+ // fst_dentry, fst_dir->i_ino, snd_dentry, snd_dir->i_ino);
ubifs_assert(ubifs_inode(fst_dir)->data_len == 0);
ubifs_assert(ubifs_inode(snd_dir)->data_len == 0);
ubifs_assert(mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex));
ubifs_assert(mutex_is_locked(&ubifs_inode(snd_dir)->ui_mutex));
- dlen1 = UBIFS_DENT_NODE_SZ + snd_dentry->d_name.len + 1;
- dlen2 = UBIFS_DENT_NODE_SZ + fst_dentry->d_name.len + 1;
+ dlen1 = UBIFS_DENT_NODE_SZ + fname_len(snd_nm) + 1;
+ dlen2 = UBIFS_DENT_NODE_SZ + fname_len(fst_nm) + 1;
aligned_dlen1 = ALIGN(dlen1, 8);
aligned_dlen2 = ALIGN(dlen2, 8);
@@ -963,24 +977,24 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
/* Make new dent for 1st entry */
dent1->ch.node_type = UBIFS_DENT_NODE;
- dent_key_init_flash(c, &dent1->key, snd_dir->i_ino, &snd_dentry->d_name);
+ dent_key_init_flash(c, &dent1->key, snd_dir->i_ino, snd_nm);
dent1->inum = cpu_to_le64(fst_inode->i_ino);
dent1->type = get_dent_type(fst_inode->i_mode);
- dent1->nlen = cpu_to_le16(snd_dentry->d_name.len);
- memcpy(dent1->name, snd_dentry->d_name.name, snd_dentry->d_name.len);
- dent1->name[snd_dentry->d_name.len] = '\0';
+ dent1->nlen = cpu_to_le16(fname_len(snd_nm));
+ memcpy(dent1->name, fname_name(snd_nm), fname_len(snd_nm));
+ dent1->name[fname_len(snd_nm)] = '\0';
zero_dent_node_unused(dent1);
ubifs_prep_grp_node(c, dent1, dlen1, 0);
/* Make new dent for 2nd entry */
dent2 = (void *)dent1 + aligned_dlen1;
dent2->ch.node_type = UBIFS_DENT_NODE;
- dent_key_init_flash(c, &dent2->key, fst_dir->i_ino, &fst_dentry->d_name);
+ dent_key_init_flash(c, &dent2->key, fst_dir->i_ino, fst_nm);
dent2->inum = cpu_to_le64(snd_inode->i_ino);
dent2->type = get_dent_type(snd_inode->i_mode);
- dent2->nlen = cpu_to_le16(fst_dentry->d_name.len);
- memcpy(dent2->name, fst_dentry->d_name.name, fst_dentry->d_name.len);
- dent2->name[fst_dentry->d_name.len] = '\0';
+ dent2->nlen = cpu_to_le16(fname_len(fst_nm));
+ memcpy(dent2->name, fname_name(fst_nm), fname_len(fst_nm));
+ dent2->name[fname_len(fst_nm)] = '\0';
zero_dent_node_unused(dent2);
ubifs_prep_grp_node(c, dent2, dlen2, 0);
@@ -1004,14 +1018,14 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
}
release_head(c, BASEHD);
- dent_key_init(c, &key, snd_dir->i_ino, &snd_dentry->d_name);
- err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, &snd_dentry->d_name);
+ dent_key_init(c, &key, snd_dir->i_ino, snd_nm);
+ err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, snd_nm);
if (err)
goto out_ro;
offs += aligned_dlen1;
- dent_key_init(c, &key, fst_dir->i_ino, &fst_dentry->d_name);
- err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, &fst_dentry->d_name);
+ dent_key_init(c, &key, fst_dir->i_ino, fst_nm);
+ err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, fst_nm);
if (err)
goto out_ro;
@@ -1063,31 +1077,31 @@ out_free:
* returned.
*/
int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
- const struct dentry *old_dentry,
+ const struct inode *old_inode,
+ const struct fscrypt_name *old_nm,
const struct inode *new_dir,
- const struct dentry *new_dentry,
+ const struct inode *new_inode,
+ const struct fscrypt_name *new_nm,
const struct inode *whiteout, int sync)
{
void *p;
union ubifs_key key;
struct ubifs_dent_node *dent, *dent2;
int err, dlen1, dlen2, ilen, lnum, offs, len;
- const struct inode *old_inode = d_inode(old_dentry);
- const struct inode *new_inode = d_inode(new_dentry);
int aligned_dlen1, aligned_dlen2, plen = UBIFS_INO_NODE_SZ;
int last_reference = !!(new_inode && new_inode->i_nlink == 0);
int move = (old_dir != new_dir);
struct ubifs_inode *uninitialized_var(new_ui);
- dbg_jnl("dent '%pd' in dir ino %lu to dent '%pd' in dir ino %lu",
- old_dentry, old_dir->i_ino, new_dentry, new_dir->i_ino);
+ //dbg_jnl("dent '%pd' in dir ino %lu to dent '%pd' in dir ino %lu",
+ // old_dentry, old_dir->i_ino, new_dentry, new_dir->i_ino);
ubifs_assert(ubifs_inode(old_dir)->data_len == 0);
ubifs_assert(ubifs_inode(new_dir)->data_len == 0);
ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex));
ubifs_assert(mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex));
- dlen1 = UBIFS_DENT_NODE_SZ + new_dentry->d_name.len + 1;
- dlen2 = UBIFS_DENT_NODE_SZ + old_dentry->d_name.len + 1;
+ dlen1 = UBIFS_DENT_NODE_SZ + fname_len(new_nm) + 1;
+ dlen2 = UBIFS_DENT_NODE_SZ + fname_len(old_nm) + 1;
if (new_inode) {
new_ui = ubifs_inode(new_inode);
ubifs_assert(mutex_is_locked(&new_ui->ui_mutex));
@@ -1113,19 +1127,19 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
/* Make new dent */
dent->ch.node_type = UBIFS_DENT_NODE;
- dent_key_init_flash(c, &dent->key, new_dir->i_ino, &new_dentry->d_name);
+ dent_key_init_flash(c, &dent->key, new_dir->i_ino, new_nm);
dent->inum = cpu_to_le64(old_inode->i_ino);
dent->type = get_dent_type(old_inode->i_mode);
- dent->nlen = cpu_to_le16(new_dentry->d_name.len);
- memcpy(dent->name, new_dentry->d_name.name, new_dentry->d_name.len);
- dent->name[new_dentry->d_name.len] = '\0';
+ dent->nlen = cpu_to_le16(fname_len(new_nm));
+ memcpy(dent->name, fname_name(new_nm), fname_len(new_nm));
+ dent->name[fname_len(new_nm)] = '\0';
+ set_dent_cookie(c, dent);
zero_dent_node_unused(dent);
ubifs_prep_grp_node(c, dent, dlen1, 0);
dent2 = (void *)dent + aligned_dlen1;
dent2->ch.node_type = UBIFS_DENT_NODE;
- dent_key_init_flash(c, &dent2->key, old_dir->i_ino,
- &old_dentry->d_name);
+ dent_key_init_flash(c, &dent2->key, old_dir->i_ino, old_nm);
if (whiteout) {
dent2->inum = cpu_to_le64(whiteout->i_ino);
@@ -1135,9 +1149,10 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
dent2->inum = 0;
dent2->type = DT_UNKNOWN;
}
- dent2->nlen = cpu_to_le16(old_dentry->d_name.len);
- memcpy(dent2->name, old_dentry->d_name.name, old_dentry->d_name.len);
- dent2->name[old_dentry->d_name.len] = '\0';
+ dent2->nlen = cpu_to_le16(fname_len(old_nm));
+ memcpy(dent2->name, fname_name(old_nm), fname_len(old_nm));
+ dent2->name[fname_len(old_nm)] = '\0';
+ set_dent_cookie(c, dent2);
zero_dent_node_unused(dent2);
ubifs_prep_grp_node(c, dent2, dlen2, 0);
@@ -1178,15 +1193,15 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
}
release_head(c, BASEHD);
- dent_key_init(c, &key, new_dir->i_ino, &new_dentry->d_name);
- err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, &new_dentry->d_name);
+ dent_key_init(c, &key, new_dir->i_ino, new_nm);
+ err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, new_nm);
if (err)
goto out_ro;
offs += aligned_dlen1;
if (whiteout) {
- dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name);
- err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, &old_dentry->d_name);
+ dent_key_init(c, &key, old_dir->i_ino, old_nm);
+ err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, old_nm);
if (err)
goto out_ro;
@@ -1196,8 +1211,8 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
if (err)
goto out_ro;
- dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name);
- err = ubifs_tnc_remove_nm(c, &key, &old_dentry->d_name);
+ dent_key_init(c, &key, old_dir->i_ino, old_nm);
+ err = ubifs_tnc_remove_nm(c, &key, old_nm);
if (err)
goto out_ro;
}
@@ -1251,31 +1266,55 @@ out_free:
}
/**
- * recomp_data_node - re-compress a truncated data node.
+ * truncate_data_node - re-compress/encrypt a truncated data node.
+ * @c: UBIFS file-system description object
+ * @inode: inode which referes to the data node
+ * @block: data block number
* @dn: data node to re-compress
* @new_len: new length
*
* This function is used when an inode is truncated and the last data node of
- * the inode has to be re-compressed and re-written.
+ * the inode has to be re-compressed/encrypted and re-written.
*/
-static int recomp_data_node(const struct ubifs_info *c,
- struct ubifs_data_node *dn, int *new_len)
+static int truncate_data_node(const struct ubifs_info *c, const struct inode *inode,
+ unsigned int block, struct ubifs_data_node *dn,
+ int *new_len)
{
void *buf;
- int err, len, compr_type, out_len;
+ int err, dlen, compr_type, out_len, old_dlen;
out_len = le32_to_cpu(dn->size);
buf = kmalloc(out_len * WORST_COMPR_FACTOR, GFP_NOFS);
if (!buf)
return -ENOMEM;
- len = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
+ dlen = old_dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
compr_type = le16_to_cpu(dn->compr_type);
- err = ubifs_decompress(c, &dn->data, len, buf, &out_len, compr_type);
- if (err)
- goto out;
- ubifs_compress(c, buf, *new_len, &dn->data, &out_len, &compr_type);
+ if (ubifs_crypt_is_encrypted(inode)) {
+ err = ubifs_decrypt(inode, dn, &dlen, block);
+ if (err)
+ goto out;
+ }
+
+ if (compr_type != UBIFS_COMPR_NONE) {
+ err = ubifs_decompress(c, &dn->data, dlen, buf, &out_len, compr_type);
+ if (err)
+ goto out;
+
+ ubifs_compress(c, buf, *new_len, &dn->data, &out_len, &compr_type);
+ }
+
+ if (ubifs_crypt_is_encrypted(inode)) {
+ err = ubifs_encrypt(inode, dn, out_len, &old_dlen, block);
+ if (err)
+ goto out;
+
+ out_len = old_dlen;
+ } else {
+ dn->compr_size = 0;
+ }
+
ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);
dn->compr_type = cpu_to_le16(compr_type);
dn->size = cpu_to_le32(*new_len);
@@ -1347,17 +1386,9 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
if (le32_to_cpu(dn->size) <= dlen)
dlen = 0; /* Nothing to do */
else {
- int compr_type = le16_to_cpu(dn->compr_type);
-
- if (compr_type != UBIFS_COMPR_NONE) {
- err = recomp_data_node(c, dn, &dlen);
- if (err)
- goto out_free;
- } else {
- dn->size = cpu_to_le32(dlen);
- dlen += UBIFS_DATA_NODE_SZ;
- }
- zero_data_node_unused(dn);
+ err = truncate_data_node(c, inode, blk, dn, &dlen);
+ if (err)
+ goto out_free;
}
}
}
@@ -1442,7 +1473,8 @@ out_free:
* error code in case of failure.
*/
int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
- const struct inode *inode, const struct qstr *nm)
+ const struct inode *inode,
+ const struct fscrypt_name *nm)
{
int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen;
struct ubifs_dent_node *xent;
@@ -1451,9 +1483,9 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
int sync = IS_DIRSYNC(host);
struct ubifs_inode *host_ui = ubifs_inode(host);
- dbg_jnl("host %lu, xattr ino %lu, name '%s', data len %d",
- host->i_ino, inode->i_ino, nm->name,
- ubifs_inode(inode)->data_len);
+ //dbg_jnl("host %lu, xattr ino %lu, name '%s', data len %d",
+ // host->i_ino, inode->i_ino, nm->name,
+ // ubifs_inode(inode)->data_len);
ubifs_assert(inode->i_nlink == 0);
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
@@ -1461,7 +1493,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
* Since we are deleting the inode, we do not bother to attach any data
* to it and assume its length is %UBIFS_INO_NODE_SZ.
*/
- xlen = UBIFS_DENT_NODE_SZ + nm->len + 1;
+ xlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1;
aligned_xlen = ALIGN(xlen, 8);
hlen = host_ui->data_len + UBIFS_INO_NODE_SZ;
len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8);
@@ -1482,9 +1514,9 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
key_write(c, &xent_key, xent->key);
xent->inum = 0;
xent->type = get_dent_type(inode->i_mode);
- xent->nlen = cpu_to_le16(nm->len);
- memcpy(xent->name, nm->name, nm->len);
- xent->name[nm->len] = '\0';
+ xent->nlen = cpu_to_le16(fname_len(nm));
+ memcpy(xent->name, fname_name(nm), fname_len(nm));
+ xent->name[fname_len(nm)] = '\0';
zero_dent_node_unused(xent);
ubifs_prep_grp_node(c, xent, xlen, 0);
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h
index c0a95e393347..7547be512db2 100644
--- a/fs/ubifs/key.h
+++ b/fs/ubifs/key.h
@@ -69,7 +69,7 @@ static inline uint32_t key_r5_hash(const char *s, int len)
uint32_t a = 0;
const signed char *str = (const signed char *)s;
- while (*str) {
+ while (len--) {
a += *str << 4;
a += *str >> 4;
a *= 11;
@@ -153,13 +153,13 @@ static inline void highest_ino_key(const struct ubifs_info *c,
* @c: UBIFS file-system description object
* @key: key to initialize
* @inum: parent inode number
- * @nm: direntry name and length
+ * @nm: direntry name and length. Not a string when encrypted!
*/
static inline void dent_key_init(const struct ubifs_info *c,
union ubifs_key *key, ino_t inum,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
- uint32_t hash = c->key_hash(nm->name, nm->len);
+ uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
key->u32[0] = inum;
@@ -191,10 +191,11 @@ static inline void dent_key_init_hash(const struct ubifs_info *c,
* @nm: direntry name and length
*/
static inline void dent_key_init_flash(const struct ubifs_info *c, void *k,
- ino_t inum, const struct qstr *nm)
+ ino_t inum,
+ const struct fscrypt_name *nm)
{
union ubifs_key *key = k;
- uint32_t hash = c->key_hash(nm->name, nm->len);
+ uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
key->j32[0] = cpu_to_le32(inum);
@@ -225,9 +226,9 @@ static inline void lowest_dent_key(const struct ubifs_info *c,
*/
static inline void xent_key_init(const struct ubifs_info *c,
union ubifs_key *key, ino_t inum,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
- uint32_t hash = c->key_hash(nm->name, nm->len);
+ uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
key->u32[0] = inum;
@@ -242,10 +243,10 @@ static inline void xent_key_init(const struct ubifs_info *c,
* @nm: extended attribute entry name and length
*/
static inline void xent_key_init_flash(const struct ubifs_info *c, void *k,
- ino_t inum, const struct qstr *nm)
+ ino_t inum, const struct fscrypt_name *nm)
{
union ubifs_key *key = k;
- uint32_t hash = c->key_hash(nm->name, nm->len);
+ uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
key->j32[0] = cpu_to_le32(inum);
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index fb0f44cd1e28..ae5c02f22f3e 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -61,7 +61,7 @@ struct replay_entry {
struct list_head list;
union ubifs_key key;
union {
- struct qstr nm;
+ struct fscrypt_name nm;
struct {
loff_t old_size;
loff_t new_size;
@@ -327,7 +327,7 @@ static void destroy_replay_list(struct ubifs_info *c)
list_for_each_entry_safe(r, tmp, &c->replay_list, list) {
if (is_hash_key(c, &r->key))
- kfree(r->nm.name);
+ kfree(fname_name(&r->nm));
list_del(&r->list);
kfree(r);
}
@@ -430,10 +430,10 @@ static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len,
r->deletion = !!deletion;
r->sqnum = sqnum;
key_copy(c, key, &r->key);
- r->nm.len = nlen;
+ fname_len(&r->nm) = nlen;
memcpy(nbuf, name, nlen);
nbuf[nlen] = '\0';
- r->nm.name = nbuf;
+ fname_name(&r->nm) = nbuf;
list_add_tail(&r->list, &c->replay_list);
return 0;
@@ -456,7 +456,7 @@ int ubifs_validate_entry(struct ubifs_info *c,
if (le32_to_cpu(dent->ch.len) != nlen + UBIFS_DENT_NODE_SZ + 1 ||
dent->type >= UBIFS_ITYPES_CNT ||
nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 ||
- strnlen(dent->name, nlen) != nlen ||
+ (key_type == UBIFS_XENT_KEY && strnlen(dent->name, nlen) != nlen) ||
le64_to_cpu(dent->inum) > MAX_INUM) {
ubifs_err(c, "bad %s node", key_type == UBIFS_DENT_KEY ?
"directory entry" : "extended attribute entry");
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index 3cbb904a6d7d..7f1ead29e727 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -163,6 +163,7 @@ static int create_default_filesystem(struct ubifs_info *c)
tmp64 = (long long)max_buds * c->leb_size;
if (big_lpt)
sup_flags |= UBIFS_FLG_BIGLPT;
+ sup_flags |= UBIFS_FLG_DOUBLE_HASH;
sup->ch.node_type = UBIFS_SB_NODE;
sup->key_hash = UBIFS_KEY_HASH_R5;
@@ -465,6 +466,16 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
goto failed;
}
+ if (!c->double_hash && c->fmt_version >= 5) {
+ err = 16;
+ goto failed;
+ }
+
+ if (c->encrypted && c->fmt_version < 5) {
+ err = 17;
+ goto failed;
+ }
+
return 0;
failed:
@@ -620,6 +631,24 @@ int ubifs_read_superblock(struct ubifs_info *c)
memcpy(&c->uuid, &sup->uuid, 16);
c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT);
c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP);
+ c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH);
+ c->encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION);
+
+ if ((sup_flags & ~UBIFS_FLG_MASK) != 0) {
+ ubifs_err(c, "Unknown feature flags found: %#x",
+ sup_flags & ~UBIFS_FLG_MASK);
+ err = -EINVAL;
+ goto out;
+ }
+
+#ifndef CONFIG_UBIFS_FS_ENCRYPTION
+ if (c->encrypted) {
+ ubifs_err(c, "file system contains encrypted files but UBIFS"
+ " was built without crypto support.");
+ err = -EINVAL;
+ goto out;
+ }
+#endif
/* Automatically increase file system size to the maximum size */
c->old_leb_cnt = c->leb_cnt;
@@ -807,3 +836,33 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
ubifs_msg(c, "free space fixup complete");
return err;
}
+
+int ubifs_enable_encryption(struct ubifs_info *c)
+{
+ int err;
+ struct ubifs_sb_node *sup;
+
+ if (c->encrypted)
+ return 0;
+
+ if (c->ro_mount || c->ro_media)
+ return -EROFS;
+
+ if (c->fmt_version < 5) {
+ ubifs_err(c, "on-flash format version 5 is needed for encryption");
+ return -EINVAL;
+ }
+
+ sup = ubifs_read_sb_node(c);
+ if (IS_ERR(sup))
+ return PTR_ERR(sup);
+
+ sup->flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION);
+
+ err = ubifs_write_sb_node(c, sup);
+ if (!err)
+ c->encrypted = 1;
+ kfree(sup);
+
+ return err;
+}
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 4ec051089186..e08aa04fc835 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -198,7 +198,6 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum)
}
memcpy(ui->data, ino->data, ui->data_len);
((char *)ui->data)[ui->data_len] = '\0';
- inode->i_link = ui->data;
break;
case S_IFBLK:
case S_IFCHR:
@@ -380,6 +379,9 @@ out:
}
done:
clear_inode(inode);
+#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+ fscrypt_put_encryption_info(inode, NULL);
+#endif
}
static void ubifs_dirty_inode(struct inode *inode, int flags)
@@ -1207,7 +1209,8 @@ static int mount_ubifs(struct ubifs_info *c)
bu_init(c);
if (!c->ro_mount) {
- c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ,
+ c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ + \
+ UBIFS_CIPHER_BLOCK_SIZE,
GFP_KERNEL);
if (!c->write_reserve_buf)
goto out_free;
@@ -1620,7 +1623,8 @@ static int ubifs_remount_rw(struct ubifs_info *c)
goto out;
}
- c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ, GFP_KERNEL);
+ c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ + \
+ UBIFS_CIPHER_BLOCK_SIZE, GFP_KERNEL);
if (!c->write_reserve_buf) {
err = -ENOMEM;
goto out;
@@ -1995,6 +1999,12 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
return c;
}
+#ifndef CONFIG_UBIFS_FS_ENCRYPTION
+struct fscrypt_operations ubifs_crypt_operations = {
+ .is_encrypted = __ubifs_crypt_is_encrypted,
+};
+#endif
+
static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
{
struct ubifs_info *c = sb->s_fs_info;
@@ -2041,6 +2051,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
sb->s_op = &ubifs_super_operations;
sb->s_xattr = ubifs_xattr_handlers;
+ sb->s_cop = &ubifs_crypt_operations;
mutex_lock(&c->umount_mutex);
err = mount_ubifs(c);
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index fa9a20cc60d6..74ae2de949df 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -378,7 +378,7 @@ static void lnc_free(struct ubifs_zbranch *zbr)
}
/**
- * tnc_read_node_nm - read a "hashed" leaf node.
+ * tnc_read_hashed_node - read a "hashed" leaf node.
* @c: UBIFS file-system description object
* @zbr: key and position of the node
* @node: node is returned here
@@ -388,8 +388,8 @@ static void lnc_free(struct ubifs_zbranch *zbr)
* added to LNC. Returns zero in case of success or a negative negative error
* code in case of failure.
*/
-static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr,
- void *node)
+static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,
+ void *node)
{
int err;
@@ -519,7 +519,7 @@ static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key,
* of failure, a negative error code is returned.
*/
static int matches_name(struct ubifs_info *c, struct ubifs_zbranch *zbr,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
struct ubifs_dent_node *dent;
int nlen, err;
@@ -542,11 +542,11 @@ static int matches_name(struct ubifs_info *c, struct ubifs_zbranch *zbr,
dent = zbr->leaf;
nlen = le16_to_cpu(dent->nlen);
- err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len));
+ err = memcmp(dent->name, fname_name(nm), min_t(int, nlen, fname_len(nm)));
if (err == 0) {
- if (nlen == nm->len)
+ if (nlen == fname_len(nm))
return NAME_MATCHES;
- else if (nlen < nm->len)
+ else if (nlen < fname_len(nm))
return NAME_LESS;
else
return NAME_GREATER;
@@ -689,7 +689,7 @@ static int tnc_prev(struct ubifs_info *c, struct ubifs_znode **zn, int *n)
*/
static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
struct ubifs_znode **zn, int *n,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
int err;
@@ -807,7 +807,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
*/
static int fallible_matches_name(struct ubifs_info *c,
struct ubifs_zbranch *zbr,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
struct ubifs_dent_node *dent;
int nlen, err;
@@ -835,11 +835,11 @@ static int fallible_matches_name(struct ubifs_info *c,
dent = zbr->leaf;
nlen = le16_to_cpu(dent->nlen);
- err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len));
+ err = memcmp(dent->name, fname_name(nm), min_t(int, nlen, fname_len(nm)));
if (err == 0) {
- if (nlen == nm->len)
+ if (nlen == fname_len(nm))
return NAME_MATCHES;
- else if (nlen < nm->len)
+ else if (nlen < fname_len(nm))
return NAME_LESS;
else
return NAME_GREATER;
@@ -878,7 +878,8 @@ out_free:
static int fallible_resolve_collision(struct ubifs_info *c,
const union ubifs_key *key,
struct ubifs_znode **zn, int *n,
- const struct qstr *nm, int adding)
+ const struct fscrypt_name *nm,
+ int adding)
{
struct ubifs_znode *o_znode = NULL, *znode = *zn;
int uninitialized_var(o_n), err, cmp, unsure = 0, nn = *n;
@@ -1453,7 +1454,7 @@ again:
* In this case the leaf node cache gets used, so we pass the
* address of the zbranch and keep the mutex locked
*/
- err = tnc_read_node_nm(c, zt, node);
+ err = tnc_read_hashed_node(c, zt, node);
goto out;
}
if (safely) {
@@ -1782,19 +1783,19 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
* @node: the node is returned here
* @nm: node name
*
- * This function look up and reads a node which contains name hash in the key.
+ * This function looks up and reads a node which contains name hash in the key.
* Since the hash may have collisions, there may be many nodes with the same
* key, so we have to sequentially look to all of them until the needed one is
* found. This function returns zero in case of success, %-ENOENT if the node
* was not found, and a negative error code in case of failure.
*/
static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
- void *node, const struct qstr *nm)
+ void *node, const struct fscrypt_name *nm)
{
int found, n, err;
struct ubifs_znode *znode;
- dbg_tnck(key, "name '%.*s' key ", nm->len, nm->name);
+ //dbg_tnck(key, "name '%.*s' key ", nm->len, nm->name);
mutex_lock(&c->tnc_mutex);
found = ubifs_lookup_level0(c, key, &znode, &n);
if (!found) {
@@ -1816,7 +1817,7 @@ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
goto out_unlock;
}
- err = tnc_read_node_nm(c, &znode->zbranch[n], node);
+ err = tnc_read_hashed_node(c, &znode->zbranch[n], node);
out_unlock:
mutex_unlock(&c->tnc_mutex);
@@ -1830,14 +1831,14 @@ out_unlock:
* @node: the node is returned here
* @nm: node name
*
- * This function look up and reads a node which contains name hash in the key.
+ * This function looks up and reads a node which contains name hash in the key.
* Since the hash may have collisions, there may be many nodes with the same
* key, so we have to sequentially look to all of them until the needed one is
* found. This function returns zero in case of success, %-ENOENT if the node
* was not found, and a negative error code in case of failure.
*/
int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
- void *node, const struct qstr *nm)
+ void *node, const struct fscrypt_name *nm)
{
int err, len;
const struct ubifs_dent_node *dent = node;
@@ -1851,16 +1852,105 @@ int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
return err;
len = le16_to_cpu(dent->nlen);
- if (nm->len == len && !memcmp(dent->name, nm->name, len))
+ if (fname_len(nm) == len && !memcmp(dent->name, fname_name(nm), len))
return 0;
/*
* Unluckily, there are hash collisions and we have to iterate over
* them look at each direntry with colliding name hash sequentially.
*/
+
return do_lookup_nm(c, key, node, nm);
}
+static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
+ struct ubifs_dent_node *dent, uint32_t cookie)
+{
+ int n, err, type = key_type(c, key);
+ struct ubifs_znode *znode;
+ struct ubifs_zbranch *zbr;
+ union ubifs_key *dkey, start_key;
+
+ ubifs_assert(is_hash_key(c, key));
+
+ lowest_dent_key(c, &start_key, key_inum(c, key));
+
+ mutex_lock(&c->tnc_mutex);
+ err = ubifs_lookup_level0(c, &start_key, &znode, &n);
+ if (unlikely(err < 0))
+ goto out_unlock;
+
+ for (;;) {
+ if (!err) {
+ err = tnc_next(c, &znode, &n);
+ if (err)
+ goto out_unlock;
+ }
+
+ zbr = &znode->zbranch[n];
+ dkey = &zbr->key;
+
+ if (key_inum(c, dkey) != key_inum(c, key) ||
+ key_type(c, dkey) != type) {
+ err = -ENOENT;
+ goto out_unlock;
+ }
+
+ err = tnc_read_hashed_node(c, zbr, dent);
+ if (err)
+ goto out_unlock;
+
+ if (key_hash(c, key) == key_hash(c, dkey) &&
+ le32_to_cpu(dent->cookie) == cookie)
+ goto out_unlock;
+ }
+
+out_unlock:
+ mutex_unlock(&c->tnc_mutex);
+ return err;
+}
+
+/**
+ * ubifs_tnc_lookup_dh - look up a "double hashed" node.
+ * @c: UBIFS file-system description object
+ * @key: node key to lookup
+ * @node: the node is returned here
+ * @cookie: node cookie for collision resolution
+ *
+ * This function looks up and reads a node which contains name hash in the key.
+ * Since the hash may have collisions, there may be many nodes with the same
+ * key, so we have to sequentially look to all of them until the needed one
+ * with the same cookie value is found.
+ * This function returns zero in case of success, %-ENOENT if the node
+ * was not found, and a negative error code in case of failure.
+ */
+int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
+ void *node, uint32_t cookie)
+{
+ int err;
+ const struct ubifs_dent_node *dent = node;
+
+ if (!c->double_hash)
+ return -EOPNOTSUPP;
+
+ /*
+ * We assume that in most of the cases there are no name collisions and
+ * 'ubifs_tnc_lookup()' returns us the right direntry.
+ */
+ err = ubifs_tnc_lookup(c, key, node);
+ if (err)
+ return err;
+
+ if (le32_to_cpu(dent->cookie) == cookie)
+ return 0;
+
+ /*
+ * Unluckily, there are hash collisions and we have to iterate over
+ * them look at each direntry with colliding name hash sequentially.
+ */
+ return do_lookup_dh(c, key, node, cookie);
+}
+
/**
* correct_parent_keys - correct parent znodes' keys.
* @c: UBIFS file-system description object
@@ -2279,14 +2369,15 @@ out_unlock:
* may have collisions, like directory entry keys.
*/
int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key,
- int lnum, int offs, int len, const struct qstr *nm)
+ int lnum, int offs, int len,
+ const struct fscrypt_name *nm)
{
int found, n, err = 0;
struct ubifs_znode *znode;
mutex_lock(&c->tnc_mutex);
- dbg_tnck(key, "LEB %d:%d, name '%.*s', key ",
- lnum, offs, nm->len, nm->name);
+ //dbg_tnck(key, "LEB %d:%d, name '%.*s', key ",
+ // lnum, offs, nm->len, nm->name);
found = lookup_level0_dirty(c, key, &znode, &n);
if (found < 0) {
err = found;
@@ -2344,7 +2435,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key,
* by passing 'ubifs_tnc_remove_nm()' the same key but
* an unmatchable name.
*/
- struct qstr noname = { .name = "" };
+ struct fscrypt_name noname = { .disk_name = { .name = "", .len = 1 } };
err = dbg_check_tnc(c, 0);
mutex_unlock(&c->tnc_mutex);
@@ -2514,13 +2605,13 @@ out_unlock:
* Returns %0 on success or negative error code on failure.
*/
int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
int n, err;
struct ubifs_znode *znode;
mutex_lock(&c->tnc_mutex);
- dbg_tnck(key, "%.*s, key ", nm->len, nm->name);
+ //dbg_tnck(key, "%.*s, key ", nm->len, nm->name);
err = lookup_level0_dirty(c, key, &znode, &n);
if (err < 0)
goto out_unlock;
@@ -2669,7 +2760,7 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum)
{
union ubifs_key key1, key2;
struct ubifs_dent_node *xent, *pxent = NULL;
- struct qstr nm = { .name = NULL };
+ struct fscrypt_name nm = {0};
dbg_tnc("ino %lu", (unsigned long)inum);
@@ -2694,8 +2785,8 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum)
dbg_tnc("xent '%s', ino %lu", xent->name,
(unsigned long)xattr_inum);
- nm.name = xent->name;
- nm.len = le16_to_cpu(xent->nlen);
+ fname_name(&nm) = xent->name;
+ fname_len(&nm) = le16_to_cpu(xent->nlen);
err = ubifs_tnc_remove_nm(c, &key1, &nm);
if (err) {
kfree(xent);
@@ -2747,7 +2838,7 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum)
*/
struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
union ubifs_key *key,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
{
int n, err, type = key_type(c, key);
struct ubifs_znode *znode;
@@ -2755,7 +2846,7 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
struct ubifs_zbranch *zbr;
union ubifs_key *dkey;
- dbg_tnck(key, "%s ", nm->name ? (char *)nm->name : "(lowest)");
+ //dbg_tnck(key, "%s ", nm->name ? (char *)nm->name : "(lowest)");
ubifs_assert(is_hash_key(c, key));
mutex_lock(&c->tnc_mutex);
@@ -2763,7 +2854,7 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
if (unlikely(err < 0))
goto out_unlock;
- if (nm->name) {
+ if (fname_len(nm) > 0) {
if (err) {
/* Handle collisions */
err = resolve_collision(c, key, &znode, &n, nm);
@@ -2813,7 +2904,7 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
goto out_free;
}
- err = tnc_read_node_nm(c, zbr, dent);
+ err = tnc_read_hashed_node(c, zbr, dent);
if (unlikely(err))
goto out_free;
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index e24380cf46ed..e8c23c9d4f4a 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -46,7 +46,7 @@
* UBIFS went into mainline kernel with format version 4. The older formats
* were development formats.
*/
-#define UBIFS_FORMAT_VERSION 4
+#define UBIFS_FORMAT_VERSION 5
/*
* Read-only compatibility version. If the UBIFS format is changed, older UBIFS
@@ -301,6 +301,13 @@ enum {
#define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ
/*
+ * xattr name of UBIFS encryption context, we don't use a prefix
+ * nor a long name to not waste space on the flash.
+ */
+#define UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT "c"
+
+
+/*
* On-flash inode flags.
*
* UBIFS_COMPR_FL: use compression for this inode
@@ -309,6 +316,7 @@ enum {
* UBIFS_APPEND_FL: writes to the inode may only append data
* UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous
* UBIFS_XATTR_FL: this inode is the inode for an extended attribute value
+ * UBIFS_CRYPT_FL: use encryption for this inode
*
* Note, these are on-flash flags which correspond to ioctl flags
* (@FS_COMPR_FL, etc). They have the same values now, but generally, do not
@@ -321,6 +329,7 @@ enum {
UBIFS_APPEND_FL = 0x08,
UBIFS_DIRSYNC_FL = 0x10,
UBIFS_XATTR_FL = 0x20,
+ UBIFS_CRYPT_FL = 0x40,
};
/* Inode flag bits used by UBIFS */
@@ -409,12 +418,19 @@ enum {
*
* UBIFS_FLG_BIGLPT: if "big" LPT model is used if set
* UBIFS_FLG_SPACE_FIXUP: first-mount "fixup" of free space within LEBs needed
+ * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to
+ * support 64bit cookies for lookups by hash
+ * UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files
*/
enum {
UBIFS_FLG_BIGLPT = 0x02,
UBIFS_FLG_SPACE_FIXUP = 0x04,
+ UBIFS_FLG_DOUBLE_HASH = 0x08,
+ UBIFS_FLG_ENCRYPTION = 0x10,
};
+#define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT|UBIFS_FLG_SPACE_FIXUP|UBIFS_FLG_DOUBLE_HASH|UBIFS_FLG_ENCRYPTION)
+
/**
* struct ubifs_ch - common header node.
* @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC)
@@ -521,7 +537,8 @@ struct ubifs_ino_node {
* @padding1: reserved for future, zeroes
* @type: type of the target inode (%UBIFS_ITYPE_REG, %UBIFS_ITYPE_DIR, etc)
* @nlen: name length
- * @padding2: reserved for future, zeroes
+ * @cookie: A 32bits random number, used to construct a 64bits
+ * identifier.
* @name: zero-terminated name
*
* Note, do not forget to amend 'zero_dent_node_unused()' function when
@@ -534,7 +551,7 @@ struct ubifs_dent_node {
__u8 padding1;
__u8 type;
__le16 nlen;
- __u8 padding2[4]; /* Watch 'zero_dent_node_unused()' if changing! */
+ __le32 cookie;
__u8 name[];
} __packed;
@@ -544,18 +561,16 @@ struct ubifs_dent_node {
* @key: node key
* @size: uncompressed data size in bytes
* @compr_type: compression type (%UBIFS_COMPR_NONE, %UBIFS_COMPR_LZO, etc)
- * @padding: reserved for future, zeroes
+ * @compr_size: compressed data size in bytes, only valid when data is encrypted
* @data: data
*
- * Note, do not forget to amend 'zero_data_node_unused()' function when
- * changing the padding fields.
*/
struct ubifs_data_node {
struct ubifs_ch ch;
__u8 key[UBIFS_MAX_KEY_LEN];
__le32 size;
__le16 compr_type;
- __u8 padding[2]; /* Watch 'zero_data_node_unused()' if changing! */
+ __le16 compr_size;
__u8 data[];
} __packed;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 096035eb29d0..ca72382ce6cc 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -38,6 +38,8 @@
#include <linux/backing-dev.h>
#include <linux/security.h>
#include <linux/xattr.h>
+#include <linux/fscrypto.h>
+#include <linux/random.h>
#include "ubifs-media.h"
/* Version of this UBIFS implementation */
@@ -83,10 +85,6 @@
*/
#define BGT_NAME_PATTERN "ubifs_bgt%d_%d"
-/* Write-buffer synchronization timeout interval in seconds */
-#define WBUF_TIMEOUT_SOFTLIMIT 3
-#define WBUF_TIMEOUT_HARDLIMIT 5
-
/* Maximum possible inode number (only 32-bit inodes are supported now) */
#define MAX_INUM 0xFFFFFFFF
@@ -138,6 +136,12 @@
*/
#define WORST_COMPR_FACTOR 2
+#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+#define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE
+#else
+#define UBIFS_CIPHER_BLOCK_SIZE 0
+#endif
+
/*
* How much memory is needed for a buffer where we compress a data node.
*/
@@ -645,9 +649,6 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c,
* @io_mutex: serializes write-buffer I/O
* @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes
* fields
- * @softlimit: soft write-buffer timeout interval
- * @delta: hard and soft timeouts delta (the timer expire interval is @softlimit
- * and @softlimit + @delta)
* @timer: write-buffer timer
* @no_timer: non-zero if this write-buffer does not have a timer
* @need_sync: non-zero if the timer expired and the wbuf needs sync'ing
@@ -676,8 +677,6 @@ struct ubifs_wbuf {
int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad);
struct mutex io_mutex;
spinlock_t lock;
- ktime_t softlimit;
- unsigned long long delta;
struct hrtimer timer;
unsigned int no_timer:1;
unsigned int need_sync:1;
@@ -1007,6 +1006,8 @@ struct ubifs_debug_info;
*
* @big_lpt: flag that LPT is too big to write whole during commit
* @space_fixup: flag indicating that free space in LEBs needs to be cleaned up
+ * @double_hash: flag indicating that we can do lookups by hash
+ * @encrypted: flag indicating that this file system contains encrypted files
* @no_chk_data_crc: do not check CRCs when reading data nodes (except during
* recovery)
* @bulk_read: enable bulk-reads
@@ -1249,6 +1250,8 @@ struct ubifs_info {
unsigned int big_lpt:1;
unsigned int space_fixup:1;
+ unsigned int double_hash:1;
+ unsigned int encrypted:1;
unsigned int no_chk_data_crc:1;
unsigned int bulk_read:1;
unsigned int default_compr:2;
@@ -1515,25 +1518,29 @@ int ubifs_consolidate_log(struct ubifs_info *c);
/* journal.c */
int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
- const struct qstr *nm, const struct inode *inode,
+ const struct fscrypt_name *nm, const struct inode *inode,
int deletion, int xent);
int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
const union ubifs_key *key, const void *buf, int len);
int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode);
int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode);
int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
- const struct dentry *fst_dentry,
+ const struct inode *fst_inode,
+ const struct fscrypt_name *fst_nm,
const struct inode *snd_dir,
- const struct dentry *snd_dentry, int sync);
+ const struct inode *snd_inode,
+ const struct fscrypt_name *snd_nm, int sync);
int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
- const struct dentry *old_dentry,
+ const struct inode *old_inode,
+ const struct fscrypt_name *old_nm,
const struct inode *new_dir,
- const struct dentry *new_dentry,
+ const struct inode *new_inode,
+ const struct fscrypt_name *new_nm,
const struct inode *whiteout, int sync);
int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
loff_t old_size, loff_t new_size);
int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
- const struct inode *inode, const struct qstr *nm);
+ const struct inode *inode, const struct fscrypt_name *nm);
int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode1,
const struct inode *inode2);
@@ -1568,7 +1575,9 @@ int ubifs_save_dirty_idx_lnums(struct ubifs_info *c);
int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
struct ubifs_znode **zn, int *n);
int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
- void *node, const struct qstr *nm);
+ void *node, const struct fscrypt_name *nm);
+int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
+ void *node, uint32_t secondary_hash);
int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
void *node, int *lnum, int *offs);
int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum,
@@ -1576,16 +1585,16 @@ int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum,
int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key,
int old_lnum, int old_offs, int lnum, int offs, int len);
int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key,
- int lnum, int offs, int len, const struct qstr *nm);
+ int lnum, int offs, int len, const struct fscrypt_name *nm);
int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key);
int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key,
- const struct qstr *nm);
+ const struct fscrypt_name *nm);
int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key,
union ubifs_key *to_key);
int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum);
struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
union ubifs_key *key,
- const struct qstr *nm);
+ const struct fscrypt_name *nm);
void ubifs_tnc_close(struct ubifs_info *c);
int ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level,
int lnum, int offs, int is_idx);
@@ -1642,6 +1651,7 @@ int ubifs_read_superblock(struct ubifs_info *c);
struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c);
int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup);
int ubifs_fixup_free_space(struct ubifs_info *c);
+int ubifs_enable_encryption(struct ubifs_info *c);
/* replay.c */
int ubifs_validate_entry(struct ubifs_info *c,
@@ -1733,16 +1743,21 @@ int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
#endif
/* dir.c */
-struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
+struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
umode_t mode);
int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
+int ubifs_check_dir_empty(struct inode *dir);
/* xattr.c */
extern const struct xattr_handler *ubifs_xattr_handlers[];
ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
int ubifs_init_security(struct inode *dentry, struct inode *inode,
const struct qstr *qstr);
+int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
+ size_t size, int flags);
+ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
+ size_t size);
/* super.c */
struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
@@ -1781,6 +1796,66 @@ int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len,
#include "misc.h"
#include "key.h"
+#ifndef CONFIG_UBIFS_FS_ENCRYPTION
+#define fscrypt_set_d_op(i)
+#define fscrypt_get_ctx fscrypt_notsupp_get_ctx
+#define fscrypt_release_ctx fscrypt_notsupp_release_ctx
+#define fscrypt_encrypt_page fscrypt_notsupp_encrypt_page
+#define fscrypt_decrypt_page fscrypt_notsupp_decrypt_page
+#define fscrypt_decrypt_bio_pages fscrypt_notsupp_decrypt_bio_pages
+#define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
+#define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
+#define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
+#define fscrypt_ioctl_set_policy fscrypt_notsupp_ioctl_set_policy
+#define fscrypt_ioctl_get_policy fscrypt_notsupp_ioctl_get_policy
+#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
+#define fscrypt_inherit_context fscrypt_notsupp_inherit_context
+#define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
+#define fscrypt_put_encryption_info fscrypt_notsupp_put_encryption_info
+#define fscrypt_setup_filename fscrypt_notsupp_setup_filename
+#define fscrypt_free_filename fscrypt_notsupp_free_filename
+#define fscrypt_fname_encrypted_size fscrypt_notsupp_fname_encrypted_size
+#define fscrypt_fname_alloc_buffer fscrypt_notsupp_fname_alloc_buffer
+#define fscrypt_fname_free_buffer fscrypt_notsupp_fname_free_buffer
+#define fscrypt_fname_disk_to_usr fscrypt_notsupp_fname_disk_to_usr
+#define fscrypt_fname_usr_to_disk fscrypt_notsupp_fname_usr_to_disk
+static inline int ubifs_encrypt(const struct inode *inode,
+ struct ubifs_data_node *dn,
+ unsigned int in_len, unsigned int *out_len,
+ int block)
+{
+ ubifs_assert(0);
+ return -EOPNOTSUPP;
+}
+static inline int ubifs_decrypt(const struct inode *inode,
+ struct ubifs_data_node *dn,
+ unsigned int *out_len, int block)
+{
+ ubifs_assert(0);
+ return -EOPNOTSUPP;
+}
+#else
+/* crypto.c */
+int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
+ unsigned int in_len, unsigned int *out_len, int block);
+int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
+ unsigned int *out_len, int block);
+#endif
+
+extern struct fscrypt_operations ubifs_crypt_operations;
+
+static inline bool __ubifs_crypt_is_encrypted(struct inode *inode)
+{
+ struct ubifs_inode *ui = ubifs_inode(inode);
+
+ return ui->flags & UBIFS_CRYPT_FL;
+}
+
+static inline bool ubifs_crypt_is_encrypted(const struct inode *inode)
+{
+ return __ubifs_crypt_is_encrypted((struct inode *)inode);
+}
+
/* Normal UBIFS messages */
__printf(2, 3)
void ubifs_msg(const struct ubifs_info *c, const char *fmt, ...);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index d9f9615bfd71..efe00fcb8b75 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -97,7 +97,7 @@ static const struct file_operations empty_fops;
* of failure.
*/
static int create_xattr(struct ubifs_info *c, struct inode *host,
- const struct qstr *nm, const void *value, int size)
+ const struct fscrypt_name *nm, const void *value, int size)
{
int err, names_len;
struct inode *inode;
@@ -117,7 +117,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
* extended attributes if the name list becomes larger. This limitation
* is artificial for UBIFS, though.
*/
- names_len = host_ui->xattr_names + host_ui->xattr_cnt + nm->len + 1;
+ names_len = host_ui->xattr_names + host_ui->xattr_cnt + fname_len(nm) + 1;
if (names_len > XATTR_LIST_MAX) {
ubifs_err(c, "cannot add one more xattr name to inode %lu, total names length would become %d, max. is %d",
host->i_ino, names_len, XATTR_LIST_MAX);
@@ -154,9 +154,18 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
mutex_lock(&host_ui->ui_mutex);
host->i_ctime = ubifs_current_time(host);
host_ui->xattr_cnt += 1;
- host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
+ host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
host_ui->xattr_size += CALC_XATTR_BYTES(size);
- host_ui->xattr_names += nm->len;
+ host_ui->xattr_names += fname_len(nm);
+
+ /*
+ * We handle UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT here because we
+ * have to set the UBIFS_CRYPT_FL flag on the host inode.
+ * To avoid multiple updates of the same inode in the same operation,
+ * let's do it here.
+ */
+ if (strcmp(fname_name(nm), UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) == 0)
+ host_ui->flags |= UBIFS_CRYPT_FL;
err = ubifs_jnl_update(c, host, nm, inode, 0, 1);
if (err)
@@ -170,9 +179,10 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
out_cancel:
host_ui->xattr_cnt -= 1;
- host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
+ host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
- host_ui->xattr_names -= nm->len;
+ host_ui->xattr_names -= fname_len(nm);
+ host_ui->flags &= ~UBIFS_CRYPT_FL;
mutex_unlock(&host_ui->ui_mutex);
out_free:
make_bad_inode(inode);
@@ -269,22 +279,28 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
return ERR_PTR(-EINVAL);
}
-static int __ubifs_setxattr(struct inode *host, const char *name,
- const void *value, size_t size, int flags)
+int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
+ size_t size, int flags)
{
struct inode *inode;
struct ubifs_info *c = host->i_sb->s_fs_info;
- struct qstr nm = QSTR_INIT(name, strlen(name));
+ struct fscrypt_name nm = { .disk_name = FSTR_INIT((char *)name, strlen(name))};
struct ubifs_dent_node *xent;
union ubifs_key key;
int err;
- ubifs_assert(inode_is_locked(host));
+ /*
+ * Creating an encryption context is done unlocked since we
+ * operate on a new inode which is not visible to other users
+ * at this point.
+ */
+ if (strcmp(name, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) != 0)
+ ubifs_assert(inode_is_locked(host));
if (size > UBIFS_MAX_INO_DATA)
return -ERANGE;
- if (nm.len > UBIFS_MAX_NLEN)
+ if (fname_len(&nm) > UBIFS_MAX_NLEN)
return -ENAMETOOLONG;
xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS);
@@ -329,18 +345,18 @@ out_free:
return err;
}
-static ssize_t __ubifs_getxattr(struct inode *host, const char *name,
- void *buf, size_t size)
+ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
+ size_t size)
{
struct inode *inode;
struct ubifs_info *c = host->i_sb->s_fs_info;
- struct qstr nm = QSTR_INIT(name, strlen(name));
+ struct fscrypt_name nm = { .disk_name = FSTR_INIT((char *)name, strlen(name))};
struct ubifs_inode *ui;
struct ubifs_dent_node *xent;
union ubifs_key key;
int err;
- if (nm.len > UBIFS_MAX_NLEN)
+ if (fname_len(&nm) > UBIFS_MAX_NLEN)
return -ENAMETOOLONG;
xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS);
@@ -387,6 +403,20 @@ out_unlock:
return err;
}
+static bool xattr_visible(const char *name)
+{
+ /* File encryption related xattrs are for internal use only */
+ if (strcmp(name, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) == 0)
+ return false;
+
+ /* Show trusted namespace only for "power" users */
+ if (strncmp(name, XATTR_TRUSTED_PREFIX,
+ XATTR_TRUSTED_PREFIX_LEN) == 0 && !capable(CAP_SYS_ADMIN))
+ return false;
+
+ return true;
+}
+
ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
union ubifs_key key;
@@ -395,7 +425,7 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct ubifs_inode *host_ui = ubifs_inode(host);
struct ubifs_dent_node *xent, *pxent = NULL;
int err, len, written = 0;
- struct qstr nm = { .name = NULL };
+ struct fscrypt_name nm = {0};
dbg_gen("ino %lu ('%pd'), buffer size %zd", host->i_ino,
dentry, size);
@@ -419,15 +449,12 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
break;
}
- nm.name = xent->name;
- nm.len = le16_to_cpu(xent->nlen);
+ fname_name(&nm) = xent->name;
+ fname_len(&nm) = le16_to_cpu(xent->nlen);
- /* Show trusted namespace only for "power" users */
- if (strncmp(xent->name, XATTR_TRUSTED_PREFIX,
- XATTR_TRUSTED_PREFIX_LEN) ||
- capable(CAP_SYS_ADMIN)) {
- memcpy(buffer + written, nm.name, nm.len + 1);
- written += nm.len + 1;
+ if (xattr_visible(xent->name)) {
+ memcpy(buffer + written, fname_name(&nm), fname_len(&nm) + 1);
+ written += fname_len(&nm) + 1;
}
kfree(pxent);
@@ -446,7 +473,7 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
}
static int remove_xattr(struct ubifs_info *c, struct inode *host,
- struct inode *inode, const struct qstr *nm)
+ struct inode *inode, const struct fscrypt_name *nm)
{
int err;
struct ubifs_inode *host_ui = ubifs_inode(host);
@@ -463,9 +490,9 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
mutex_lock(&host_ui->ui_mutex);
host->i_ctime = ubifs_current_time(host);
host_ui->xattr_cnt -= 1;
- host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
+ host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len);
- host_ui->xattr_names -= nm->len;
+ host_ui->xattr_names -= fname_len(nm);
err = ubifs_jnl_delete_xattr(c, host, inode, nm);
if (err)
@@ -477,27 +504,27 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
out_cancel:
host_ui->xattr_cnt += 1;
- host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
+ host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
- host_ui->xattr_names += nm->len;
+ host_ui->xattr_names += fname_len(nm);
mutex_unlock(&host_ui->ui_mutex);
ubifs_release_budget(c, &req);
make_bad_inode(inode);
return err;
}
-static int __ubifs_removexattr(struct inode *host, const char *name)
+static int ubifs_xattr_remove(struct inode *host, const char *name)
{
struct inode *inode;
struct ubifs_info *c = host->i_sb->s_fs_info;
- struct qstr nm = QSTR_INIT(name, strlen(name));
+ struct fscrypt_name nm = { .disk_name = FSTR_INIT((char *)name, strlen(name))};
struct ubifs_dent_node *xent;
union ubifs_key key;
int err;
ubifs_assert(inode_is_locked(host));
- if (nm.len > UBIFS_MAX_NLEN)
+ if (fname_len(&nm) > UBIFS_MAX_NLEN)
return -ENAMETOOLONG;
xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS);
@@ -548,7 +575,8 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
}
strcpy(name, XATTR_SECURITY_PREFIX);
strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
- err = __ubifs_setxattr(inode, name, xattr->value, xattr->value_len, 0);
+ err = ubifs_xattr_set(inode, name, xattr->value,
+ xattr->value_len, 0);
kfree(name);
if (err < 0)
break;
@@ -572,7 +600,7 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
return err;
}
-static int ubifs_xattr_get(const struct xattr_handler *handler,
+static int xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *buffer, size_t size)
{
@@ -580,10 +608,10 @@ static int ubifs_xattr_get(const struct xattr_handler *handler,
inode->i_ino, dentry, size);
name = xattr_full_name(handler, name);
- return __ubifs_getxattr(inode, name, buffer, size);
+ return ubifs_xattr_get(inode, name, buffer, size);
}
-static int ubifs_xattr_set(const struct xattr_handler *handler,
+static int xattr_set(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)
@@ -594,27 +622,27 @@ static int ubifs_xattr_set(const struct xattr_handler *handler,
name = xattr_full_name(handler, name);
if (value)
- return __ubifs_setxattr(inode, name, value, size, flags);
+ return ubifs_xattr_set(inode, name, value, size, flags);
else
- return __ubifs_removexattr(inode, name);
+ return ubifs_xattr_remove(inode, name);
}
static const struct xattr_handler ubifs_user_xattr_handler = {
.prefix = XATTR_USER_PREFIX,
- .get = ubifs_xattr_get,
- .set = ubifs_xattr_set,
+ .get = xattr_get,
+ .set = xattr_set,
};
static const struct xattr_handler ubifs_trusted_xattr_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
- .get = ubifs_xattr_get,
- .set = ubifs_xattr_set,
+ .get = xattr_get,
+ .set = xattr_set,
};
static const struct xattr_handler ubifs_security_xattr_handler = {
.prefix = XATTR_SECURITY_PREFIX,
- .get = ubifs_xattr_get,
- .set = ubifs_xattr_set,
+ .get = xattr_get,
+ .set = xattr_set,
};
const struct xattr_handler *ubifs_xattr_handlers[] = {
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index effb64cf714f..5050056a0b06 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2455,12 +2455,15 @@ xfs_agf_verify(
be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)))
return false;
- if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
+ if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
return false;
if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)
+ (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS))
return false;
/*
@@ -2477,7 +2480,8 @@ xfs_agf_verify(
return false;
if (xfs_sb_version_hasreflink(&mp->m_sb) &&
- be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS)
+ (be32_to_cpu(agf->agf_refcount_level) < 1 ||
+ be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
return false;
return true;;
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c
index 5ba2dac5e67c..efb467b10a71 100644
--- a/fs/xfs/libxfs/xfs_alloc_btree.c
+++ b/fs/xfs/libxfs/xfs_alloc_btree.c
@@ -421,13 +421,17 @@ xfs_allocbt_init_cursor(
ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
- cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
+ cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
cur->bc_tp = tp;
cur->bc_mp = mp;
cur->bc_btnum = btnum;
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_ops = &xfs_allocbt_ops;
+ if (btnum == XFS_BTNUM_BNO)
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
+ else
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
if (btnum == XFS_BTNUM_CNT) {
cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 8ea91f363093..2852521fc8ec 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -253,6 +253,7 @@ xfs_attr3_leaf_verify(
{
struct xfs_mount *mp = bp->b_target->bt_mount;
struct xfs_attr_leafblock *leaf = bp->b_addr;
+ struct xfs_perag *pag = bp->b_pag;
struct xfs_attr3_icleaf_hdr ichdr;
xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
@@ -273,7 +274,12 @@ xfs_attr3_leaf_verify(
if (ichdr.magic != XFS_ATTR_LEAF_MAGIC)
return false;
}
- if (ichdr.count == 0)
+ /*
+ * In recovery there is a transient state where count == 0 is valid
+ * because we may have transitioned an empty shortform attr to a leaf
+ * if the attr didn't fit in shortform.
+ */
+ if (pag && pag->pagf_init && ichdr.count == 0)
return false;
/* XXX: need to range check rest of attr header values */
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
index 4f2aed04f827..f7dda0c237b0 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.h
+++ b/fs/xfs/libxfs/xfs_attr_leaf.h
@@ -51,7 +51,7 @@ int xfs_attr_shortform_getvalue(struct xfs_da_args *args);
int xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
int xfs_attr_shortform_remove(struct xfs_da_args *args);
int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp);
-int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
+int xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes);
void xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp);
/*
@@ -77,7 +77,7 @@ int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
struct xfs_da_args *args);
int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
struct xfs_da_args *args);
-int xfs_attr3_leaf_list_int(struct xfs_buf *bp,
+void xfs_attr3_leaf_list_int(struct xfs_buf *bp,
struct xfs_attr_list_context *context);
/*
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index c6eb21940783..2760bc3b2536 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -49,6 +49,8 @@
#include "xfs_rmap.h"
#include "xfs_ag_resv.h"
#include "xfs_refcount.h"
+#include "xfs_rmap_btree.h"
+#include "xfs_icache.h"
kmem_zone_t *xfs_bmap_free_item_zone;
@@ -190,8 +192,12 @@ xfs_bmap_worst_indlen(
int maxrecs; /* maximum record count at this level */
xfs_mount_t *mp; /* mount structure */
xfs_filblks_t rval; /* return value */
+ xfs_filblks_t orig_len;
mp = ip->i_mount;
+
+ /* Calculate the worst-case size of the bmbt. */
+ orig_len = len;
maxrecs = mp->m_bmap_dmxr[0];
for (level = 0, rval = 0;
level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
@@ -199,12 +205,20 @@ xfs_bmap_worst_indlen(
len += maxrecs - 1;
do_div(len, maxrecs);
rval += len;
- if (len == 1)
- return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
+ if (len == 1) {
+ rval += XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
level - 1;
+ break;
+ }
if (level == 0)
maxrecs = mp->m_bmap_dmxr[1];
}
+
+ /* Calculate the worst-case size of the rmapbt. */
+ if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+ rval += 1 + xfs_rmapbt_calc_size(mp, orig_len) +
+ mp->m_rmap_maxlevels;
+
return rval;
}
@@ -504,7 +518,7 @@ void
xfs_bmap_trace_exlist(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t cnt, /* count of entries in the list */
- int whichfork, /* data or attr fork */
+ int whichfork, /* data or attr or cow fork */
unsigned long caller_ip)
{
xfs_extnum_t idx; /* extent record index */
@@ -513,11 +527,13 @@ xfs_bmap_trace_exlist(
if (whichfork == XFS_ATTR_FORK)
state |= BMAP_ATTRFORK;
+ else if (whichfork == XFS_COW_FORK)
+ state |= BMAP_COWFORK;
ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
+ ASSERT(cnt == xfs_iext_count(ifp));
for (idx = 0; idx < cnt; idx++)
- trace_xfs_extlist(ip, idx, whichfork, caller_ip);
+ trace_xfs_extlist(ip, idx, state, caller_ip);
}
/*
@@ -811,7 +827,7 @@ try_another_ag:
XFS_BTREE_LONG_PTRS);
arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
for (cnt = i = 0; i < nextents; i++) {
ep = xfs_iext_get_ext(ifp, i);
if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) {
@@ -1137,6 +1153,10 @@ xfs_bmap_add_attrfork(
goto trans_cancel;
if (XFS_IFORK_Q(ip))
goto trans_cancel;
+ if (ip->i_d.di_anextents != 0) {
+ error = -EFSCORRUPTED;
+ goto trans_cancel;
+ }
if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
/*
* For inodes coming from pre-6.2 filesystems.
@@ -1144,7 +1164,6 @@ xfs_bmap_add_attrfork(
ASSERT(ip->i_d.di_aformat == 0);
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
}
- ASSERT(ip->i_d.di_anextents == 0);
xfs_trans_ijoin(tp, ip, 0);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
@@ -1296,7 +1315,7 @@ xfs_bmap_read_extents(
/*
* Here with bp and block set to the leftmost leaf node in the tree.
*/
- room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ room = xfs_iext_count(ifp);
i = 0;
/*
* Loop over all leaf nodes. Copy information to the extent records.
@@ -1361,8 +1380,9 @@ xfs_bmap_read_extents(
return error;
block = XFS_BUF_TO_BLOCK(bp);
}
- ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
- ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
+ if (i != XFS_IFORK_NEXTENTS(ip, whichfork))
+ return -EFSCORRUPTED;
+ ASSERT(i == xfs_iext_count(ifp));
XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
return 0;
error0:
@@ -1370,97 +1390,6 @@ error0:
return -EFSCORRUPTED;
}
-
-/*
- * Search the extent records for the entry containing block bno.
- * If bno lies in a hole, point to the next entry. If bno lies
- * past eof, *eofp will be set, and *prevp will contain the last
- * entry (null if none). Else, *lastxp will be set to the index
- * of the found entry; *gotp will contain the entry.
- */
-STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
-xfs_bmap_search_multi_extents(
- xfs_ifork_t *ifp, /* inode fork pointer */
- xfs_fileoff_t bno, /* block number searched for */
- int *eofp, /* out: end of file found */
- xfs_extnum_t *lastxp, /* out: last extent index */
- xfs_bmbt_irec_t *gotp, /* out: extent entry found */
- xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
-{
- xfs_bmbt_rec_host_t *ep; /* extent record pointer */
- xfs_extnum_t lastx; /* last extent index */
-
- /*
- * Initialize the extent entry structure to catch access to
- * uninitialized br_startblock field.
- */
- gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
- gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
- gotp->br_state = XFS_EXT_INVALID;
- gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
- prevp->br_startoff = NULLFILEOFF;
-
- ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
- if (lastx > 0) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
- }
- if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
- xfs_bmbt_get_all(ep, gotp);
- *eofp = 0;
- } else {
- if (lastx > 0) {
- *gotp = *prevp;
- }
- *eofp = 1;
- ep = NULL;
- }
- *lastxp = lastx;
- return ep;
-}
-
-/*
- * Search the extents list for the inode, for the extent containing bno.
- * If bno lies in a hole, point to the next entry. If bno lies past eof,
- * *eofp will be set, and *prevp will contain the last entry (null if none).
- * Else, *lastxp will be set to the index of the found
- * entry; *gotp will contain the entry.
- */
-xfs_bmbt_rec_host_t * /* pointer to found extent entry */
-xfs_bmap_search_extents(
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_fileoff_t bno, /* block number searched for */
- int fork, /* data or attr fork */
- int *eofp, /* out: end of file found */
- xfs_extnum_t *lastxp, /* out: last extent index */
- xfs_bmbt_irec_t *gotp, /* out: extent entry found */
- xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
-{
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_host_t *ep; /* extent record pointer */
-
- XFS_STATS_INC(ip->i_mount, xs_look_exlist);
- ifp = XFS_IFORK_PTR(ip, fork);
-
- ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
-
- if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
- !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
- xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
- "Access to block zero in inode %llu "
- "start_block: %llx start_off: %llx "
- "blkcnt: %llx extent-state: %x lastx: %x",
- (unsigned long long)ip->i_ino,
- (unsigned long long)gotp->br_startblock,
- (unsigned long long)gotp->br_startoff,
- (unsigned long long)gotp->br_blockcount,
- gotp->br_state, *lastxp);
- *lastxp = NULLEXTNUM;
- *eofp = 1;
- return NULL;
- }
- return ep;
-}
-
/*
* Returns the file-relative block number of the first unused block(s)
* in the file with at least "len" logically contiguous blocks free.
@@ -1497,7 +1426,7 @@ xfs_bmap_first_unused(
(error = xfs_iread_extents(tp, ip, whichfork)))
return error;
lowest = *first_unused;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
off = xfs_bmbt_get_startoff(ep);
@@ -1523,44 +1452,44 @@ xfs_bmap_first_unused(
*/
int /* error */
xfs_bmap_last_before(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_inode_t *ip, /* incore inode */
- xfs_fileoff_t *last_block, /* last block */
- int whichfork) /* data or attr fork */
+ struct xfs_trans *tp, /* transaction pointer */
+ struct xfs_inode *ip, /* incore inode */
+ xfs_fileoff_t *last_block, /* last block */
+ int whichfork) /* data or attr fork */
{
- xfs_fileoff_t bno; /* input file offset */
- int eof; /* hit end of file */
- xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
- int error; /* error return value */
- xfs_bmbt_irec_t got; /* current extent value */
- xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_extnum_t lastx; /* last extent used */
- xfs_bmbt_irec_t prev; /* previous extent value */
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
+ struct xfs_bmbt_irec got;
+ xfs_extnum_t idx;
+ int error;
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
- return -EIO;
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
+ switch (XFS_IFORK_FORMAT(ip, whichfork)) {
+ case XFS_DINODE_FMT_LOCAL:
*last_block = 0;
return 0;
+ case XFS_DINODE_FMT_BTREE:
+ case XFS_DINODE_FMT_EXTENTS:
+ break;
+ default:
+ return -EIO;
}
- ifp = XFS_IFORK_PTR(ip, whichfork);
- if (!(ifp->if_flags & XFS_IFEXTENTS) &&
- (error = xfs_iread_extents(tp, ip, whichfork)))
- return error;
- bno = *last_block - 1;
- ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
- &prev);
- if (eof || xfs_bmbt_get_startoff(ep) > bno) {
- if (prev.br_startoff == NULLFILEOFF)
- *last_block = 0;
- else
- *last_block = prev.br_startoff + prev.br_blockcount;
+
+ if (!(ifp->if_flags & XFS_IFEXTENTS)) {
+ error = xfs_iread_extents(tp, ip, whichfork);
+ if (error)
+ return error;
}
- /*
- * Otherwise *last_block is already the right answer.
- */
+
+ if (xfs_iext_lookup_extent(ip, ifp, *last_block - 1, &idx, &got)) {
+ if (got.br_startoff <= *last_block - 1)
+ return 0;
+ }
+
+ if (xfs_iext_get_extent(ifp, idx - 1, &got)) {
+ *last_block = got.br_startoff + got.br_blockcount;
+ return 0;
+ }
+
+ *last_block = 0;
return 0;
}
@@ -1582,7 +1511,7 @@ xfs_bmap_last_extent(
return error;
}
- nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
if (nextents == 0) {
*is_empty = 1;
return 0;
@@ -1735,7 +1664,7 @@ xfs_bmap_add_extent_delay_real(
&bma->ip->i_d.di_nextents);
ASSERT(bma->idx >= 0);
- ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
+ ASSERT(bma->idx <= xfs_iext_count(ifp));
ASSERT(!isnullstartblock(new->br_startblock));
ASSERT(!bma->cur ||
(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
@@ -1794,7 +1723,7 @@ xfs_bmap_add_extent_delay_real(
* Don't set contiguous if the combined extent would be too large.
* Also check for all-three-contiguous being too large.
*/
- if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
+ if (bma->idx < xfs_iext_count(ifp) - 1) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT);
@@ -2300,7 +2229,7 @@ xfs_bmap_add_extent_unwritten_real(
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
ASSERT(*idx >= 0);
- ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
+ ASSERT(*idx <= xfs_iext_count(ifp));
ASSERT(!isnullstartblock(new->br_startblock));
XFS_STATS_INC(mp, xs_add_exlist);
@@ -2356,7 +2285,7 @@ xfs_bmap_add_extent_unwritten_real(
* Don't set contiguous if the combined extent would be too large.
* Also check for all-three-contiguous being too large.
*/
- if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
+ if (*idx < xfs_iext_count(&ip->i_df) - 1) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT);
if (isnullstartblock(RIGHT.br_startblock))
@@ -2836,7 +2765,7 @@ xfs_bmap_add_extent_hole_delay(
* Check and set flags if the current (right) segment exists.
* If it doesn't exist, we're converting the hole at end-of-file.
*/
- if (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
+ if (*idx < xfs_iext_count(ifp)) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right);
@@ -2966,7 +2895,7 @@ xfs_bmap_add_extent_hole_real(
ifp = XFS_IFORK_PTR(bma->ip, whichfork);
ASSERT(bma->idx >= 0);
- ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
+ ASSERT(bma->idx <= xfs_iext_count(ifp));
ASSERT(!isnullstartblock(new->br_startblock));
ASSERT(!bma->cur ||
!(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
@@ -2992,7 +2921,7 @@ xfs_bmap_add_extent_hole_real(
* Check and set flags if this segment has a current value.
* Not true if we're inserting into the "hole" at eof.
*/
- if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
+ if (bma->idx < xfs_iext_count(ifp)) {
state |= BMAP_RIGHT_VALID;
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &right);
if (isnullstartblock(right.br_startblock))
@@ -4145,12 +4074,11 @@ xfs_bmapi_read(
struct xfs_mount *mp = ip->i_mount;
struct xfs_ifork *ifp;
struct xfs_bmbt_irec got;
- struct xfs_bmbt_irec prev;
xfs_fileoff_t obno;
xfs_fileoff_t end;
- xfs_extnum_t lastx;
+ xfs_extnum_t idx;
int error;
- int eof;
+ bool eof = false;
int n = 0;
int whichfork = xfs_bmapi_whichfork(flags);
@@ -4190,7 +4118,8 @@ xfs_bmapi_read(
return error;
}
- xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev);
+ if (!xfs_iext_lookup_extent(ip, ifp, bno, &idx, &got))
+ eof = true;
end = bno + len;
obno = bno;
@@ -4221,10 +4150,8 @@ xfs_bmapi_read(
break;
/* Else go on to the next record. */
- if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
- else
- eof = 1;
+ if (!xfs_iext_get_extent(ifp, ++idx, &got))
+ eof = true;
}
*nmap = n;
return 0;
@@ -4234,10 +4161,10 @@ int
xfs_bmapi_reserve_delalloc(
struct xfs_inode *ip,
int whichfork,
- xfs_fileoff_t aoff,
+ xfs_fileoff_t off,
xfs_filblks_t len,
+ xfs_filblks_t prealloc,
struct xfs_bmbt_irec *got,
- struct xfs_bmbt_irec *prev,
xfs_extnum_t *lastx,
int eof)
{
@@ -4248,10 +4175,17 @@ xfs_bmapi_reserve_delalloc(
char rt = XFS_IS_REALTIME_INODE(ip);
xfs_extlen_t extsz;
int error;
+ xfs_fileoff_t aoff = off;
- alen = XFS_FILBLKS_MIN(len, MAXEXTLEN);
+ /*
+ * Cap the alloc length. Keep track of prealloc so we know whether to
+ * tag the inode before we return.
+ */
+ alen = XFS_FILBLKS_MIN(len + prealloc, MAXEXTLEN);
if (!eof)
alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
+ if (prealloc && alen >= len)
+ prealloc = alen - len;
/* Figure out the extent size, adjust alen */
if (whichfork == XFS_COW_FORK)
@@ -4259,7 +4193,12 @@ xfs_bmapi_reserve_delalloc(
else
extsz = xfs_get_extsz_hint(ip);
if (extsz) {
- error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof,
+ struct xfs_bmbt_irec prev;
+
+ if (!xfs_iext_get_extent(ifp, *lastx - 1, &prev))
+ prev.br_startoff = NULLFILEOFF;
+
+ error = xfs_bmap_extsize_align(mp, got, &prev, extsz, rt, eof,
1, 0, &aoff, &alen);
ASSERT(!error);
}
@@ -4312,6 +4251,16 @@ xfs_bmapi_reserve_delalloc(
*/
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got);
+ /*
+ * Tag the inode if blocks were preallocated. Note that COW fork
+ * preallocation can occur at the start or end of the extent, even when
+ * prealloc == 0, so we must also check the aligned offset and length.
+ */
+ if (whichfork == XFS_DATA_FORK && prealloc)
+ xfs_inode_set_eofblocks_tag(ip);
+ if (whichfork == XFS_COW_FORK && (prealloc || aoff < off || alen > len))
+ xfs_inode_set_cowblocks_tag(ip);
+
ASSERT(got->br_startoff <= aoff);
ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen);
ASSERT(isnullstartblock(got->br_startblock));
@@ -4349,7 +4298,7 @@ xfs_bmapi_allocate(
if (bma->wasdel) {
bma->length = (xfs_extlen_t)bma->got.br_blockcount;
bma->offset = bma->got.br_startoff;
- if (bma->idx != NULLEXTNUM && bma->idx) {
+ if (bma->idx) {
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1),
&bma->prev);
}
@@ -4563,7 +4512,7 @@ xfs_bmapi_write(
struct xfs_ifork *ifp;
struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */
xfs_fileoff_t end; /* end of mapped file region */
- int eof; /* after the end of extents */
+ bool eof = false; /* after the end of extents */
int error; /* error return */
int n; /* current extent index */
xfs_fileoff_t obno; /* old block number (offset) */
@@ -4641,12 +4590,14 @@ xfs_bmapi_write(
goto error0;
}
- xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got,
- &bma.prev);
n = 0;
end = bno + len;
obno = bno;
+ if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.idx, &bma.got))
+ eof = true;
+ if (!xfs_iext_get_extent(ifp, bma.idx - 1, &bma.prev))
+ bma.prev.br_startoff = NULLFILEOFF;
bma.tp = tp;
bma.ip = ip;
bma.total = total;
@@ -4733,11 +4684,8 @@ xfs_bmapi_write(
/* Else go on to the next record. */
bma.prev = bma.got;
- if (++bma.idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) {
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx),
- &bma.got);
- } else
- eof = 1;
+ if (!xfs_iext_get_extent(ifp, ++bma.idx, &bma.got))
+ eof = true;
}
*nmap = n;
@@ -4885,7 +4833,7 @@ xfs_bmap_del_extent_delay(
da_new = 0;
ASSERT(*idx >= 0);
- ASSERT(*idx < ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
+ ASSERT(*idx <= xfs_iext_count(ifp));
ASSERT(del->br_blockcount > 0);
ASSERT(got->br_startoff <= del->br_startoff);
ASSERT(got_endoff >= del_endoff);
@@ -4902,8 +4850,11 @@ xfs_bmap_del_extent_delay(
* sb counters as we might have to borrow some blocks for the
* indirect block accounting.
*/
- xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del->br_blockcount), 0,
+ error = xfs_trans_reserve_quota_nblks(NULL, ip,
+ -((long)del->br_blockcount), 0,
isrt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+ if (error)
+ return error;
ip->i_delayed_blks -= del->br_blockcount;
if (whichfork == XFS_COW_FORK)
@@ -5013,7 +4964,7 @@ xfs_bmap_del_extent_cow(
got_endoff = got->br_startoff + got->br_blockcount;
ASSERT(*idx >= 0);
- ASSERT(*idx < ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
+ ASSERT(*idx <= xfs_iext_count(ifp));
ASSERT(del->br_blockcount > 0);
ASSERT(got->br_startoff <= del->br_startoff);
ASSERT(got_endoff >= del_endoff);
@@ -5119,8 +5070,7 @@ xfs_bmap_del_extent(
state |= BMAP_COWFORK;
ifp = XFS_IFORK_PTR(ip, whichfork);
- ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
- (uint)sizeof(xfs_bmbt_rec_t)));
+ ASSERT((*idx >= 0) && (*idx < xfs_iext_count(ifp)));
ASSERT(del->br_blockcount > 0);
ep = xfs_iext_get_ext(ifp, *idx);
xfs_bmbt_get_all(ep, &got);
@@ -5434,8 +5384,6 @@ __xfs_bunmapi(
{
xfs_btree_cur_t *cur; /* bmap btree cursor */
xfs_bmbt_irec_t del; /* extent being deleted */
- int eof; /* is deleting at eof */
- xfs_bmbt_rec_host_t *ep; /* extent record pointer */
int error; /* error return value */
xfs_extnum_t extno; /* extent number in list */
xfs_bmbt_irec_t got; /* current extent record */
@@ -5445,8 +5393,6 @@ __xfs_bunmapi(
int logflags; /* transaction logging flags */
xfs_extlen_t mod; /* rt extent offset */
xfs_mount_t *mp; /* mount structure */
- xfs_extnum_t nextents; /* number of file extents */
- xfs_bmbt_irec_t prev; /* previous extent record */
xfs_fileoff_t start; /* first file offset deleted */
int tmp_logflags; /* partial logging flags */
int wasdel; /* was a delayed alloc extent */
@@ -5477,8 +5423,7 @@ __xfs_bunmapi(
if (!(ifp->if_flags & XFS_IFEXTENTS) &&
(error = xfs_iread_extents(tp, ip, whichfork)))
return error;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- if (nextents == 0) {
+ if (xfs_iext_count(ifp) == 0) {
*rlen = 0;
return 0;
}
@@ -5486,18 +5431,17 @@ __xfs_bunmapi(
isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
start = bno;
bno = start + len - 1;
- ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
- &prev);
/*
* Check to see if the given block number is past the end of the
* file, back up to the last block if so...
*/
- if (eof) {
- ep = xfs_iext_get_ext(ifp, --lastx);
- xfs_bmbt_get_all(ep, &got);
+ if (!xfs_iext_lookup_extent(ip, ifp, bno, &lastx, &got)) {
+ ASSERT(lastx > 0);
+ xfs_iext_get_extent(ifp, --lastx, &got);
bno = got.br_startoff + got.br_blockcount - 1;
}
+
logflags = 0;
if (ifp->if_flags & XFS_IFBROOT) {
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
@@ -5528,8 +5472,7 @@ __xfs_bunmapi(
if (got.br_startoff > bno) {
if (--lastx < 0)
break;
- ep = xfs_iext_get_ext(ifp, lastx);
- xfs_bmbt_get_all(ep, &got);
+ xfs_iext_get_extent(ifp, lastx, &got);
}
/*
* Is the last block of this extent before the range
@@ -5543,7 +5486,6 @@ __xfs_bunmapi(
* Then deal with the (possibly delayed) allocated space
* we found.
*/
- ASSERT(ep != NULL);
del = got;
wasdel = isnullstartblock(del.br_startblock);
if (got.br_startoff < start) {
@@ -5624,15 +5566,12 @@ __xfs_bunmapi(
*/
ASSERT(bno >= del.br_blockcount);
bno -= del.br_blockcount;
- if (got.br_startoff > bno) {
- if (--lastx >= 0) {
- ep = xfs_iext_get_ext(ifp,
- lastx);
- xfs_bmbt_get_all(ep, &got);
- }
- }
+ if (got.br_startoff > bno && --lastx >= 0)
+ xfs_iext_get_extent(ifp, lastx, &got);
continue;
} else if (del.br_state == XFS_EXT_UNWRITTEN) {
+ struct xfs_bmbt_irec prev;
+
/*
* This one is already unwritten.
* It must have a written left neighbor.
@@ -5640,8 +5579,7 @@ __xfs_bunmapi(
* try again.
*/
ASSERT(lastx > 0);
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
- lastx - 1), &prev);
+ xfs_iext_get_extent(ifp, lastx - 1, &prev);
ASSERT(prev.br_state == XFS_EXT_NORM);
ASSERT(!isnullstartblock(prev.br_startblock));
ASSERT(del.br_startblock ==
@@ -5739,13 +5677,9 @@ nodelete:
*/
if (bno != (xfs_fileoff_t)-1 && bno >= start) {
if (lastx >= 0) {
- ep = xfs_iext_get_ext(ifp, lastx);
- if (xfs_bmbt_get_startoff(ep) > bno) {
- if (--lastx >= 0)
- ep = xfs_iext_get_ext(ifp,
- lastx);
- }
- xfs_bmbt_get_all(ep, &got);
+ xfs_iext_get_extent(ifp, lastx, &got);
+ if (got.br_startoff > bno && --lastx >= 0)
+ xfs_iext_get_extent(ifp, lastx, &got);
}
extno++;
}
@@ -5963,7 +5897,7 @@ xfs_bmse_shift_one(
mp = ip->i_mount;
ifp = XFS_IFORK_PTR(ip, whichfork);
- total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+ total_extents = xfs_iext_count(ifp);
xfs_bmbt_get_all(gotp, &got);
@@ -6140,7 +6074,7 @@ xfs_bmap_shift_extents(
* are collapsing out, so we cannot use the count of real extents here.
* Instead we have to calculate it from the incore fork.
*/
- total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+ total_extents = xfs_iext_count(ifp);
if (total_extents == 0) {
*done = 1;
goto del_cursor;
@@ -6200,7 +6134,7 @@ xfs_bmap_shift_extents(
* count can change. Update the total and grade the next record.
*/
if (direction == SHIFT_LEFT) {
- total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+ total_extents = xfs_iext_count(ifp);
stop_extent = total_extents;
}
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index 7cae6ec27fa6..cecd094404cc 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -237,14 +237,9 @@ int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip,
struct xfs_defer_ops *dfops, enum shift_direction direction,
int num_exts);
int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset);
-struct xfs_bmbt_rec_host *
- xfs_bmap_search_extents(struct xfs_inode *ip, xfs_fileoff_t bno,
- int fork, int *eofp, xfs_extnum_t *lastxp,
- struct xfs_bmbt_irec *gotp, struct xfs_bmbt_irec *prevp);
int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork,
- xfs_fileoff_t aoff, xfs_filblks_t len,
- struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *prev,
- xfs_extnum_t *lastx, int eof);
+ xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc,
+ struct xfs_bmbt_irec *got, xfs_extnum_t *lastx, int eof);
enum xfs_bmap_intent_type {
XFS_BMAP_MAP = 1,
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index 8007d2ba9aef..d6330c297ca0 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -796,13 +796,14 @@ xfs_bmbt_init_cursor(
struct xfs_btree_cur *cur;
ASSERT(whichfork != XFS_COW_FORK);
- cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
+ cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
cur->bc_tp = tp;
cur->bc_mp = mp;
cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
cur->bc_btnum = XFS_BTNUM_BMAP;
cur->bc_blocklog = mp->m_sb.sb_blocklog;
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
cur->bc_ops = &xfs_bmbt_ops;
cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 0e80993c8a59..21e6a6ab6b9a 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -1769,8 +1769,28 @@ xfs_btree_lookup_get_block(
if (error)
return error;
+ /* Check the inode owner since the verifiers don't. */
+ if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) &&
+ (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
+ be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
+ cur->bc_private.b.ip->i_ino)
+ goto out_bad;
+
+ /* Did we get the level we were looking for? */
+ if (be16_to_cpu((*blkp)->bb_level) != level)
+ goto out_bad;
+
+ /* Check that internal nodes have at least one record. */
+ if (level != 0 && be16_to_cpu((*blkp)->bb_numrecs) == 0)
+ goto out_bad;
+
xfs_btree_setbuf(cur, level, bp);
return 0;
+
+out_bad:
+ *blkp = NULL;
+ xfs_trans_brelse(cur->bc_tp, bp);
+ return -EFSCORRUPTED;
}
/*
diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h
index c2b01d1c79ee..b69b947c4c1b 100644
--- a/fs/xfs/libxfs/xfs_btree.h
+++ b/fs/xfs/libxfs/xfs_btree.h
@@ -96,46 +96,10 @@ union xfs_btree_rec {
/*
* Generic stats interface
*/
-#define __XFS_BTREE_STATS_INC(mp, type, stat) \
- XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat)
#define XFS_BTREE_STATS_INC(cur, stat) \
-do { \
- struct xfs_mount *__mp = cur->bc_mp; \
- switch (cur->bc_btnum) { \
- case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(__mp, abtb, stat); break; \
- case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(__mp, abtc, stat); break; \
- case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(__mp, bmbt, stat); break; \
- case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(__mp, ibt, stat); break; \
- case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(__mp, fibt, stat); break; \
- case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(__mp, rmap, stat); break; \
- case XFS_BTNUM_REFC: __XFS_BTREE_STATS_INC(__mp, refcbt, stat); break; \
- case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
- } \
-} while (0)
-
-#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \
- XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val)
-#define XFS_BTREE_STATS_ADD(cur, stat, val) \
-do { \
- struct xfs_mount *__mp = cur->bc_mp; \
- switch (cur->bc_btnum) { \
- case XFS_BTNUM_BNO: \
- __XFS_BTREE_STATS_ADD(__mp, abtb, stat, val); break; \
- case XFS_BTNUM_CNT: \
- __XFS_BTREE_STATS_ADD(__mp, abtc, stat, val); break; \
- case XFS_BTNUM_BMAP: \
- __XFS_BTREE_STATS_ADD(__mp, bmbt, stat, val); break; \
- case XFS_BTNUM_INO: \
- __XFS_BTREE_STATS_ADD(__mp, ibt, stat, val); break; \
- case XFS_BTNUM_FINO: \
- __XFS_BTREE_STATS_ADD(__mp, fibt, stat, val); break; \
- case XFS_BTNUM_RMAP: \
- __XFS_BTREE_STATS_ADD(__mp, rmap, stat, val); break; \
- case XFS_BTNUM_REFC: \
- __XFS_BTREE_STATS_ADD(__mp, refcbt, stat, val); break; \
- case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
- } \
-} while (0)
+ XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat)
+#define XFS_BTREE_STATS_ADD(cur, stat, val) \
+ XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val)
#define XFS_BTREE_MAXLEVELS 9 /* max of all btrees */
@@ -253,6 +217,7 @@ typedef struct xfs_btree_cur
__uint8_t bc_nlevels; /* number of levels in the tree */
__uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */
xfs_btnum_t bc_btnum; /* identifies which btree type */
+ int bc_statoff; /* offset of btre stats array */
union {
struct { /* needed for BNO, CNT, INO */
struct xfs_buf *agbp; /* agf/agi buffer pointer */
diff --git a/fs/xfs/libxfs/xfs_cksum.h b/fs/xfs/libxfs/xfs_cksum.h
index fad1676ad8cd..a416c7cb23ea 100644
--- a/fs/xfs/libxfs/xfs_cksum.h
+++ b/fs/xfs/libxfs/xfs_cksum.h
@@ -6,10 +6,11 @@
/*
* Calculate the intermediate checksum for a buffer that has the CRC field
* inside it. The offset of the 32bit crc fields is passed as the
- * cksum_offset parameter.
+ * cksum_offset parameter. We do not modify the buffer during verification,
+ * hence we have to split the CRC calculation across the cksum_offset.
*/
static inline __uint32_t
-xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+xfs_start_cksum_safe(char *buffer, size_t length, unsigned long cksum_offset)
{
__uint32_t zero = 0;
__uint32_t crc;
@@ -26,6 +27,20 @@ xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset)
}
/*
+ * Fast CRC method where the buffer is modified. Callers must have exclusive
+ * access to the buffer while the calculation takes place.
+ */
+static inline __uint32_t
+xfs_start_cksum_update(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ /* zero the CRC field */
+ *(__le32 *)(buffer + cksum_offset) = 0;
+
+ /* single pass CRC calculation for the entire buffer */
+ return crc32c(XFS_CRC_SEED, buffer, length);
+}
+
+/*
* Convert the intermediate checksum to the final ondisk format.
*
* The CRC32c calculation uses LE format even on BE machines, but returns the
@@ -40,11 +55,14 @@ xfs_end_cksum(__uint32_t crc)
/*
* Helper to generate the checksum for a buffer.
+ *
+ * This modifies the buffer temporarily - callers must have exclusive
+ * access to the buffer while the calculation takes place.
*/
static inline void
xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
{
- __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
+ __uint32_t crc = xfs_start_cksum_update(buffer, length, cksum_offset);
*(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
}
@@ -55,7 +73,7 @@ xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
static inline int
xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
{
- __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
+ __uint32_t crc = xfs_start_cksum_safe(buffer, length, cksum_offset);
return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
}
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 20a96dd5af7e..c58d72c220f5 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -93,7 +93,7 @@ xfs_ascii_ci_compname(
return result;
}
-static struct xfs_nameops xfs_ascii_ci_nameops = {
+static const struct xfs_nameops xfs_ascii_ci_nameops = {
.hashname = xfs_ascii_ci_hashname,
.compname = xfs_ascii_ci_compname,
};
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index becc926c3e3d..0197590fa7d7 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -157,6 +157,9 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
struct xfs_buf *bp);
+extern void xfs_dir2_data_freescan_int(struct xfs_da_geometry *geo,
+ const struct xfs_dir_ops *ops,
+ struct xfs_dir2_data_hdr *hdr, int *loghead);
extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
struct xfs_dir2_data_hdr *hdr, int *loghead);
extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
@@ -177,6 +180,8 @@ extern struct xfs_dir2_data_free *xfs_dir2_data_freefind(
struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
struct xfs_dir2_data_unused *dup);
+extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
+
extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 725fc7841fde..d478065b9544 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -329,7 +329,7 @@ xfs_dir3_data_read(
err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
- if (!err && tp)
+ if (!err && tp && *bpp)
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
return err;
}
@@ -505,8 +505,9 @@ xfs_dir2_data_freeremove(
* Given a data block, reconstruct its bestfree map.
*/
void
-xfs_dir2_data_freescan(
- struct xfs_inode *dp,
+xfs_dir2_data_freescan_int(
+ struct xfs_da_geometry *geo,
+ const struct xfs_dir_ops *ops,
struct xfs_dir2_data_hdr *hdr,
int *loghead)
{
@@ -516,7 +517,6 @@ xfs_dir2_data_freescan(
struct xfs_dir2_data_free *bf;
char *endp; /* end of block's data */
char *p; /* current entry pointer */
- struct xfs_da_geometry *geo = dp->i_mount->m_dir_geo;
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@@ -526,13 +526,13 @@ xfs_dir2_data_freescan(
/*
* Start by clearing the table.
*/
- bf = dp->d_ops->data_bestfree_p(hdr);
+ bf = ops->data_bestfree_p(hdr);
memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
*loghead = 1;
/*
* Set up pointers.
*/
- p = (char *)dp->d_ops->data_entry_p(hdr);
+ p = (char *)ops->data_entry_p(hdr);
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
btp = xfs_dir2_block_tail_p(geo, hdr);
@@ -559,12 +559,22 @@ xfs_dir2_data_freescan(
else {
dep = (xfs_dir2_data_entry_t *)p;
ASSERT((char *)dep - (char *)hdr ==
- be16_to_cpu(*dp->d_ops->data_entry_tag_p(dep)));
- p += dp->d_ops->data_entsize(dep->namelen);
+ be16_to_cpu(*ops->data_entry_tag_p(dep)));
+ p += ops->data_entsize(dep->namelen);
}
}
}
+void
+xfs_dir2_data_freescan(
+ struct xfs_inode *dp,
+ struct xfs_dir2_data_hdr *hdr,
+ int *loghead)
+{
+ return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops,
+ hdr, loghead);
+}
+
/*
* Initialize a data block at the given block number in the directory.
* Give back the buffer for the created block.
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index ef9f6ead96a4..d04547fcf274 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -21,7 +21,6 @@
struct dir_context;
/* xfs_dir2.c */
-extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
xfs_dir2_db_t *dbp);
extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 51b4e0de1fdc..f272abff11e1 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -2344,7 +2344,8 @@ xfs_imap(
imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno);
imap->im_len = XFS_FSB_TO_BB(mp, 1);
- imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog);
+ imap->im_boffset = (unsigned short)(offset <<
+ mp->m_sb.sb_inodelog);
return 0;
}
@@ -2372,7 +2373,7 @@ out_map:
imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno);
imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster);
- imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog);
+ imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog);
/*
* If the inode number maps to a block outside the bounds
@@ -2450,8 +2451,6 @@ xfs_ialloc_log_agi(
ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
#endif
- xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGI_BUF);
-
/*
* Compute byte offsets for the first and last fields in the first
* region and log the agi buffer. This only logs up through
@@ -2512,8 +2511,15 @@ xfs_agi_verify(
if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)))
return false;
- if (be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
+ if (be32_to_cpu(agi->agi_level) < 1 ||
+ be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
+ return false;
+
+ if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
+ (be32_to_cpu(agi->agi_free_level) < 1 ||
+ be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS))
return false;
+
/*
* during growfs operations, the perag is not fully initialised,
* so we can't use it for any useful checking. growfs ensures we can't
@@ -2592,6 +2598,8 @@ xfs_read_agi(
XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops);
if (error)
return error;
+ if (tp)
+ xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_AGI_BUF);
xfs_buf_set_ref(*bpp, XFS_AGI_REF);
return 0;
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index eab68ae2e011..0fd086d03d41 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -357,7 +357,7 @@ xfs_inobt_init_cursor(
struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
struct xfs_btree_cur *cur;
- cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
+ cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
cur->bc_tp = tp;
cur->bc_mp = mp;
@@ -365,9 +365,11 @@ xfs_inobt_init_cursor(
if (btnum == XFS_BTNUM_INO) {
cur->bc_nlevels = be32_to_cpu(agi->agi_level);
cur->bc_ops = &xfs_inobt_ops;
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2);
} else {
cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
cur->bc_ops = &xfs_finobt_ops;
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
}
cur->bc_blocklog = mp->m_sb.sb_blocklog;
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 134424fac434..dd483e2767f7 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -383,7 +383,7 @@ xfs_log_dinode_to_disk(
static bool
xfs_dinode_verify(
struct xfs_mount *mp,
- struct xfs_inode *ip,
+ xfs_ino_t ino,
struct xfs_dinode *dip)
{
uint16_t flags;
@@ -392,6 +392,14 @@ xfs_dinode_verify(
if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
return false;
+ /* don't allow invalid i_size */
+ if (be64_to_cpu(dip->di_size) & (1ULL << 63))
+ return false;
+
+ /* No zero-length symlinks. */
+ if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0)
+ return false;
+
/* only version 3 or greater inodes are extensively verified here */
if (dip->di_version < 3)
return true;
@@ -401,7 +409,7 @@ xfs_dinode_verify(
if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
XFS_DINODE_CRC_OFF))
return false;
- if (be64_to_cpu(dip->di_ino) != ip->i_ino)
+ if (be64_to_cpu(dip->di_ino) != ino)
return false;
if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_meta_uuid))
return false;
@@ -436,7 +444,7 @@ xfs_dinode_calc_crc(
return;
ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
- crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
+ crc = xfs_start_cksum_update((char *)dip, mp->m_sb.sb_inodesize,
XFS_DINODE_CRC_OFF);
dip->di_crc = xfs_end_cksum(crc);
}
@@ -493,7 +501,7 @@ xfs_iread(
return error;
/* even unallocated inodes are verified */
- if (!xfs_dinode_verify(mp, ip, dip)) {
+ if (!xfs_dinode_verify(mp, ip->i_ino, dip)) {
xfs_alert(mp, "%s: validation failed for inode %lld failed",
__func__, ip->i_ino);
diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h
index 3cfe12a4f58a..6848a0afbce7 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.h
+++ b/fs/xfs/libxfs/xfs_inode_buf.h
@@ -58,8 +58,8 @@ struct xfs_icdinode {
*/
struct xfs_imap {
xfs_daddr_t im_blkno; /* starting BB of inode chunk */
- ushort im_len; /* length in BBs of inode chunk */
- ushort im_boffset; /* inode offset in block in bytes */
+ unsigned short im_len; /* length in BBs of inode chunk */
+ unsigned short im_boffset; /* inode offset in block in bytes */
};
int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 5dd56d3dbb3a..222e103356c6 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -775,6 +775,13 @@ xfs_idestroy_fork(
}
}
+/* Count number of incore extents based on if_bytes */
+xfs_extnum_t
+xfs_iext_count(struct xfs_ifork *ifp)
+{
+ return ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+}
+
/*
* Convert in-core extents to on-disk form
*
@@ -803,7 +810,7 @@ xfs_iextents_copy(
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
ASSERT(ifp->if_bytes > 0);
- nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nrecs = xfs_iext_count(ifp);
XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork);
ASSERT(nrecs > 0);
@@ -941,7 +948,7 @@ xfs_iext_get_ext(
xfs_extnum_t idx) /* index of target extent */
{
ASSERT(idx >= 0);
- ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
+ ASSERT(idx < xfs_iext_count(ifp));
if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
return ifp->if_u1.if_ext_irec->er_extbuf;
@@ -1017,7 +1024,7 @@ xfs_iext_add(
int new_size; /* size of extents after adding */
xfs_extnum_t nextents; /* number of extents in file */
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
ASSERT((idx >= 0) && (idx <= nextents));
byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
new_size = ifp->if_bytes + byte_diff;
@@ -1241,7 +1248,7 @@ xfs_iext_remove(
trace_xfs_iext_remove(ip, idx, state, _RET_IP_);
ASSERT(ext_diff > 0);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
if (new_size == 0) {
@@ -1270,7 +1277,7 @@ xfs_iext_remove_inline(
ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
ASSERT(idx < XFS_INLINE_EXTS);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
ASSERT(((nextents - ext_diff) > 0) &&
(nextents - ext_diff) < XFS_INLINE_EXTS);
@@ -1309,7 +1316,7 @@ xfs_iext_remove_direct(
ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
new_size = ifp->if_bytes -
(ext_diff * sizeof(xfs_bmbt_rec_t));
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
if (new_size == 0) {
xfs_iext_destroy(ifp);
@@ -1546,7 +1553,7 @@ xfs_iext_indirect_to_direct(
int size; /* size of file extents */
ASSERT(ifp->if_flags & XFS_IFEXTIREC);
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
ASSERT(nextents <= XFS_LINEAR_EXTS);
size = nextents * sizeof(xfs_bmbt_rec_t);
@@ -1620,7 +1627,7 @@ xfs_iext_bno_to_ext(
xfs_extnum_t nextents; /* number of file extents */
xfs_fileoff_t startoff = 0; /* start offset of extent */
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
if (nextents == 0) {
*idxp = 0;
return NULL;
@@ -1733,8 +1740,8 @@ xfs_iext_idx_to_irec(
ASSERT(ifp->if_flags & XFS_IFEXTIREC);
ASSERT(page_idx >= 0);
- ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
- ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc);
+ ASSERT(page_idx <= xfs_iext_count(ifp));
+ ASSERT(page_idx < xfs_iext_count(ifp) || realloc);
nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
erp_idx = 0;
@@ -1782,7 +1789,7 @@ xfs_iext_irec_init(
xfs_extnum_t nextents; /* number of extents in file */
ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
ASSERT(nextents <= XFS_LINEAR_EXTS);
erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS);
@@ -1906,7 +1913,7 @@ xfs_iext_irec_compact(
ASSERT(ifp->if_flags & XFS_IFEXTIREC);
nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
if (nextents == 0) {
xfs_iext_destroy(ifp);
@@ -1996,3 +2003,49 @@ xfs_ifork_init_cow(
ip->i_cformat = XFS_DINODE_FMT_EXTENTS;
ip->i_cnextents = 0;
}
+
+/*
+ * Lookup the extent covering bno.
+ *
+ * If there is an extent covering bno return the extent index, and store the
+ * expanded extent structure in *gotp, and the extent index in *idx.
+ * If there is no extent covering bno, but there is an extent after it (e.g.
+ * it lies in a hole) return that extent in *gotp and its index in *idx
+ * instead.
+ * If bno is beyond the last extent return false, and return the index after
+ * the last valid index in *idxp.
+ */
+bool
+xfs_iext_lookup_extent(
+ struct xfs_inode *ip,
+ struct xfs_ifork *ifp,
+ xfs_fileoff_t bno,
+ xfs_extnum_t *idxp,
+ struct xfs_bmbt_irec *gotp)
+{
+ struct xfs_bmbt_rec_host *ep;
+
+ XFS_STATS_INC(ip->i_mount, xs_look_exlist);
+
+ ep = xfs_iext_bno_to_ext(ifp, bno, idxp);
+ if (!ep)
+ return false;
+ xfs_bmbt_get_all(ep, gotp);
+ return true;
+}
+
+/*
+ * Return true if there is an extent at index idx, and return the expanded
+ * extent structure at idx in that case. Else return false.
+ */
+bool
+xfs_iext_get_extent(
+ struct xfs_ifork *ifp,
+ xfs_extnum_t idx,
+ struct xfs_bmbt_irec *gotp)
+{
+ if (idx < 0 || idx >= xfs_iext_count(ifp))
+ return false;
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), gotp);
+ return true;
+}
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index c9476f50e32d..7fb8365326d1 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -152,6 +152,7 @@ void xfs_init_local_fork(struct xfs_inode *, int, const void *, int);
struct xfs_bmbt_rec_host *
xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
+xfs_extnum_t xfs_iext_count(struct xfs_ifork *);
void xfs_iext_insert(struct xfs_inode *, xfs_extnum_t, xfs_extnum_t,
struct xfs_bmbt_irec *, int);
void xfs_iext_add(struct xfs_ifork *, xfs_extnum_t, int);
@@ -181,6 +182,12 @@ void xfs_iext_irec_compact_pages(struct xfs_ifork *);
void xfs_iext_irec_compact_full(struct xfs_ifork *);
void xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int);
+bool xfs_iext_lookup_extent(struct xfs_inode *ip,
+ struct xfs_ifork *ifp, xfs_fileoff_t bno,
+ xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp);
+bool xfs_iext_get_extent(struct xfs_ifork *ifp, xfs_extnum_t idx,
+ struct xfs_bmbt_irec *gotp);
+
extern struct kmem_zone *xfs_ifork_zone;
extern void xfs_ifork_init_cow(struct xfs_inode *ip);
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index 083cdd6d6c28..7ae571f8e34a 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -481,8 +481,8 @@ static inline uint xfs_log_dinode_size(int version)
typedef struct xfs_buf_log_format {
unsigned short blf_type; /* buf log item type indicator */
unsigned short blf_size; /* size of this item */
- ushort blf_flags; /* misc state */
- ushort blf_len; /* number of blocks in this buf */
+ unsigned short blf_flags; /* misc state */
+ unsigned short blf_len; /* number of blocks in this buf */
__int64_t blf_blkno; /* starting blkno of this buf */
unsigned int blf_map_size; /* used size of data bitmap in words */
unsigned int blf_data_map[XFS_BLF_DATAMAP_SIZE]; /* dirty bitmap */
diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h
index 8e385f91d660..d9f65e2d5cc8 100644
--- a/fs/xfs/libxfs/xfs_log_recover.h
+++ b/fs/xfs/libxfs/xfs_log_recover.h
@@ -52,7 +52,7 @@ typedef struct xlog_recover {
struct list_head r_itemq; /* q for items */
} xlog_recover_t;
-#define ITEM_TYPE(i) (*(ushort *)(i)->ri_buf[0].i_addr)
+#define ITEM_TYPE(i) (*(unsigned short *)(i)->ri_buf[0].i_addr)
/*
* This is the number of entries in the l_buf_cancel_table used during
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 453bb2757ec2..6fb2215f8ff7 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -354,6 +354,7 @@ xfs_refcountbt_init_cursor(
cur->bc_btnum = XFS_BTNUM_REFC;
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_ops = &xfs_refcountbt_ops;
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index 83e672ff7577..de25771764ba 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -484,6 +484,7 @@ xfs_rmapbt_init_cursor(
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_ops = &xfs_rmapbt_ops;
cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
cur->bc_private.a.agbp = agbp;
cur->bc_private.a.agno = agno;
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index e2e1106c9fad..ea45584a9913 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1016,4 +1016,3 @@ xfs_rtfree_extent(
}
return 0;
}
-
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index a70aec910626..2580262e4ea0 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -262,6 +262,12 @@ xfs_mount_validate_sb(
return -EFSCORRUPTED;
}
+ if (xfs_sb_version_hascrc(&mp->m_sb) &&
+ sbp->sb_blocksize < XFS_MIN_CRC_BLOCKSIZE) {
+ xfs_notice(mp, "v5 SB sanity check failed");
+ return -EFSCORRUPTED;
+ }
+
/*
* Until this is fixed only page-sized or smaller data blocks work.
*/
@@ -338,13 +344,16 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp)
XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD;
sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD);
- if (sbp->sb_qflags & XFS_PQUOTA_ACCT) {
+ if (sbp->sb_qflags & XFS_PQUOTA_ACCT &&
+ sbp->sb_gquotino != NULLFSINO) {
/*
* In older version of superblock, on-disk superblock only
* has sb_gquotino, and in-core superblock has both sb_gquotino
* and sb_pquotino. But, only one of them is supported at any
* point of time. So, if PQUOTA is set in disk superblock,
- * copy over sb_gquotino to sb_pquotino.
+ * copy over sb_gquotino to sb_pquotino. The NULLFSINO test
+ * above is to make sure we don't do this twice and wipe them
+ * both out!
*/
sbp->sb_pquotino = sbp->sb_gquotino;
sbp->sb_gquotino = NULLFSINO;
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 8d74870468c2..717909f2f7b7 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -57,7 +57,6 @@ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */
#define NULLAGBLOCK ((xfs_agblock_t)-1)
#define NULLAGNUMBER ((xfs_agnumber_t)-1)
-#define NULLEXTNUM ((xfs_extnum_t)-1)
#define NULLCOMMITLSN ((xfs_lsn_t)-1)
@@ -75,11 +74,14 @@ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */
* Minimum and maximum blocksize and sectorsize.
* The blocksize upper limit is pretty much arbitrary.
* The sectorsize upper limit is due to sizeof(sb_sectsize).
+ * CRC enable filesystems use 512 byte inodes, meaning 512 byte block sizes
+ * cannot be used.
*/
#define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */
#define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */
#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG)
#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG)
+#define XFS_MIN_CRC_BLOCKSIZE (1 << (XFS_MIN_BLOCKSIZE_LOG + 1))
#define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */
#define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */
#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG)
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 38755ca96c7a..0f56fcd3a5d5 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -37,11 +37,6 @@
#include <linux/pagevec.h>
#include <linux/writeback.h>
-/* flags for direct write completions */
-#define XFS_DIO_FLAG_UNWRITTEN (1 << 0)
-#define XFS_DIO_FLAG_APPEND (1 << 1)
-#define XFS_DIO_FLAG_COW (1 << 2)
-
/*
* structure owned by writepages passed to individual writepage calls
*/
@@ -776,7 +771,7 @@ xfs_map_cow(
{
struct xfs_inode *ip = XFS_I(inode);
struct xfs_bmbt_irec imap;
- bool is_cow = false, need_alloc = false;
+ bool is_cow = false;
int error;
/*
@@ -794,7 +789,7 @@ xfs_map_cow(
* Else we need to check if there is a COW mapping at this offset.
*/
xfs_ilock(ip, XFS_ILOCK_SHARED);
- is_cow = xfs_reflink_find_cow_mapping(ip, offset, &imap, &need_alloc);
+ is_cow = xfs_reflink_find_cow_mapping(ip, offset, &imap);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (!is_cow)
@@ -804,7 +799,7 @@ xfs_map_cow(
* And if the COW mapping has a delayed extent here we need to
* allocate real space for it now.
*/
- if (need_alloc) {
+ if (isnullstartblock(imap.br_startblock)) {
error = xfs_iomap_write_allocate(ip, XFS_COW_FORK, offset,
&imap);
if (error)
@@ -1175,45 +1170,6 @@ xfs_vm_releasepage(
}
/*
- * When we map a DIO buffer, we may need to pass flags to
- * xfs_end_io_direct_write to tell it what kind of write IO we are doing.
- *
- * Note that for DIO, an IO to the highest supported file block offset (i.e.
- * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64
- * bit variable. Hence if we see this overflow, we have to assume that the IO is
- * extending the file size. We won't know for sure until IO completion is run
- * and the actual max write offset is communicated to the IO completion
- * routine.
- */
-static void
-xfs_map_direct(
- struct inode *inode,
- struct buffer_head *bh_result,
- struct xfs_bmbt_irec *imap,
- xfs_off_t offset,
- bool is_cow)
-{
- uintptr_t *flags = (uintptr_t *)&bh_result->b_private;
- xfs_off_t size = bh_result->b_size;
-
- trace_xfs_get_blocks_map_direct(XFS_I(inode), offset, size,
- ISUNWRITTEN(imap) ? XFS_IO_UNWRITTEN : is_cow ? XFS_IO_COW :
- XFS_IO_OVERWRITE, imap);
-
- if (ISUNWRITTEN(imap)) {
- *flags |= XFS_DIO_FLAG_UNWRITTEN;
- set_buffer_defer_completion(bh_result);
- } else if (is_cow) {
- *flags |= XFS_DIO_FLAG_COW;
- set_buffer_defer_completion(bh_result);
- }
- if (offset + size > i_size_read(inode) || offset + size < 0) {
- *flags |= XFS_DIO_FLAG_APPEND;
- set_buffer_defer_completion(bh_result);
- }
-}
-
-/*
* If this is O_DIRECT or the mpage code calling tell them how large the mapping
* is, so that we can avoid repeated get_blocks calls.
*
@@ -1253,51 +1209,12 @@ xfs_map_trim_size(
bh_result->b_size = mapping_size;
}
-/* Bounce unaligned directio writes to the page cache. */
static int
-xfs_bounce_unaligned_dio_write(
- struct xfs_inode *ip,
- xfs_fileoff_t offset_fsb,
- struct xfs_bmbt_irec *imap)
-{
- struct xfs_bmbt_irec irec;
- xfs_fileoff_t delta;
- bool shared;
- bool x;
- int error;
-
- irec = *imap;
- if (offset_fsb > irec.br_startoff) {
- delta = offset_fsb - irec.br_startoff;
- irec.br_blockcount -= delta;
- irec.br_startblock += delta;
- irec.br_startoff = offset_fsb;
- }
- error = xfs_reflink_trim_around_shared(ip, &irec, &shared, &x);
- if (error)
- return error;
-
- /*
- * We're here because we're trying to do a directio write to a
- * region that isn't aligned to a filesystem block. If any part
- * of the extent is shared, fall back to buffered mode to handle
- * the RMW. This is done by returning -EREMCHG ("remote addr
- * changed"), which is caught further up the call stack.
- */
- if (shared) {
- trace_xfs_reflink_bounce_dio_write(ip, imap);
- return -EREMCHG;
- }
- return 0;
-}
-
-STATIC int
-__xfs_get_blocks(
+xfs_get_blocks(
struct inode *inode,
sector_t iblock,
struct buffer_head *bh_result,
- int create,
- bool direct)
+ int create)
{
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
@@ -1308,11 +1225,8 @@ __xfs_get_blocks(
int nimaps = 1;
xfs_off_t offset;
ssize_t size;
- int new = 0;
- bool is_cow = false;
- bool need_alloc = false;
- BUG_ON(create && !direct);
+ BUG_ON(create);
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
@@ -1321,7 +1235,7 @@ __xfs_get_blocks(
ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
size = bh_result->b_size;
- if (!create && offset >= i_size_read(inode))
+ if (offset >= i_size_read(inode))
return 0;
/*
@@ -1336,52 +1250,12 @@ __xfs_get_blocks(
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
offset_fsb = XFS_B_TO_FSBT(mp, offset);
- if (create && direct && xfs_is_reflink_inode(ip))
- is_cow = xfs_reflink_find_cow_mapping(ip, offset, &imap,
- &need_alloc);
- if (!is_cow) {
- error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
- &imap, &nimaps, XFS_BMAPI_ENTIRE);
- /*
- * Truncate an overwrite extent if there's a pending CoW
- * reservation before the end of this extent. This
- * forces us to come back to get_blocks to take care of
- * the CoW.
- */
- if (create && direct && nimaps &&
- imap.br_startblock != HOLESTARTBLOCK &&
- imap.br_startblock != DELAYSTARTBLOCK &&
- !ISUNWRITTEN(&imap))
- xfs_reflink_trim_irec_to_next_cow(ip, offset_fsb,
- &imap);
- }
- ASSERT(!need_alloc);
+ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+ &imap, &nimaps, XFS_BMAPI_ENTIRE);
if (error)
goto out_unlock;
- /* for DAX, we convert unwritten extents directly */
- if (create &&
- (!nimaps ||
- (imap.br_startblock == HOLESTARTBLOCK ||
- imap.br_startblock == DELAYSTARTBLOCK) ||
- (IS_DAX(inode) && ISUNWRITTEN(&imap)))) {
- /*
- * xfs_iomap_write_direct() expects the shared lock. It
- * is unlocked on return.
- */
- if (lockmode == XFS_ILOCK_EXCL)
- xfs_ilock_demote(ip, lockmode);
-
- error = xfs_iomap_write_direct(ip, offset, size,
- &imap, nimaps);
- if (error)
- return error;
- new = 1;
-
- trace_xfs_get_blocks_alloc(ip, offset, size,
- ISUNWRITTEN(&imap) ? XFS_IO_UNWRITTEN
- : XFS_IO_DELALLOC, &imap);
- } else if (nimaps) {
+ if (nimaps) {
trace_xfs_get_blocks_found(ip, offset, size,
ISUNWRITTEN(&imap) ? XFS_IO_UNWRITTEN
: XFS_IO_OVERWRITE, &imap);
@@ -1391,12 +1265,6 @@ __xfs_get_blocks(
goto out_unlock;
}
- if (IS_DAX(inode) && create) {
- ASSERT(!ISUNWRITTEN(&imap));
- /* zeroing is not needed at a higher layer */
- new = 0;
- }
-
/* trim mapping down to size requested */
xfs_map_trim_size(inode, iblock, bh_result, &imap, offset, size);
@@ -1406,45 +1274,14 @@ __xfs_get_blocks(
*/
if (imap.br_startblock != HOLESTARTBLOCK &&
imap.br_startblock != DELAYSTARTBLOCK &&
- (create || !ISUNWRITTEN(&imap))) {
- if (create && direct && !is_cow) {
- error = xfs_bounce_unaligned_dio_write(ip, offset_fsb,
- &imap);
- if (error)
- return error;
- }
-
+ !ISUNWRITTEN(&imap))
xfs_map_buffer(inode, bh_result, &imap, offset);
- if (ISUNWRITTEN(&imap))
- set_buffer_unwritten(bh_result);
- /* direct IO needs special help */
- if (create)
- xfs_map_direct(inode, bh_result, &imap, offset, is_cow);
- }
/*
* If this is a realtime file, data may be on a different device.
* to that pointed to from the buffer_head b_bdev currently.
*/
bh_result->b_bdev = xfs_find_bdev_for_inode(inode);
-
- /*
- * If we previously allocated a block out beyond eof and we are now
- * coming back to use it then we will need to flag it as new even if it
- * has a disk address.
- *
- * With sub-block writes into unwritten extents we also need to mark
- * the buffer as new so that the unwritten parts of the buffer gets
- * correctly zeroed.
- */
- if (create &&
- ((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
- (offset >= i_size_read(inode)) ||
- (new || ISUNWRITTEN(&imap))))
- set_buffer_new(bh_result);
-
- BUG_ON(direct && imap.br_startblock == DELAYSTARTBLOCK);
-
return 0;
out_unlock:
@@ -1452,100 +1289,6 @@ out_unlock:
return error;
}
-int
-xfs_get_blocks(
- struct inode *inode,
- sector_t iblock,
- struct buffer_head *bh_result,
- int create)
-{
- return __xfs_get_blocks(inode, iblock, bh_result, create, false);
-}
-
-int
-xfs_get_blocks_direct(
- struct inode *inode,
- sector_t iblock,
- struct buffer_head *bh_result,
- int create)
-{
- return __xfs_get_blocks(inode, iblock, bh_result, create, true);
-}
-
-/*
- * Complete a direct I/O write request.
- *
- * xfs_map_direct passes us some flags in the private data to tell us what to
- * do. If no flags are set, then the write IO is an overwrite wholly within
- * the existing allocated file size and so there is nothing for us to do.
- *
- * Note that in this case the completion can be called in interrupt context,
- * whereas if we have flags set we will always be called in task context
- * (i.e. from a workqueue).
- */
-int
-xfs_end_io_direct_write(
- struct kiocb *iocb,
- loff_t offset,
- ssize_t size,
- void *private)
-{
- struct inode *inode = file_inode(iocb->ki_filp);
- struct xfs_inode *ip = XFS_I(inode);
- uintptr_t flags = (uintptr_t)private;
- int error = 0;
-
- trace_xfs_end_io_direct_write(ip, offset, size);
-
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return -EIO;
-
- if (size <= 0)
- return size;
-
- /*
- * The flags tell us whether we are doing unwritten extent conversions
- * or an append transaction that updates the on-disk file size. These
- * cases are the only cases where we should *potentially* be needing
- * to update the VFS inode size.
- */
- if (flags == 0) {
- ASSERT(offset + size <= i_size_read(inode));
- return 0;
- }
-
- /*
- * We need to update the in-core inode size here so that we don't end up
- * with the on-disk inode size being outside the in-core inode size. We
- * have no other method of updating EOF for AIO, so always do it here
- * if necessary.
- *
- * We need to lock the test/set EOF update as we can be racing with
- * other IO completions here to update the EOF. Failing to serialise
- * here can result in EOF moving backwards and Bad Things Happen when
- * that occurs.
- */
- spin_lock(&ip->i_flags_lock);
- if (offset + size > i_size_read(inode))
- i_size_write(inode, offset + size);
- spin_unlock(&ip->i_flags_lock);
-
- if (flags & XFS_DIO_FLAG_COW)
- error = xfs_reflink_end_cow(ip, offset, size);
- if (flags & XFS_DIO_FLAG_UNWRITTEN) {
- trace_xfs_end_io_direct_write_unwritten(ip, offset, size);
-
- error = xfs_iomap_write_unwritten(ip, offset, size);
- }
- if (flags & XFS_DIO_FLAG_APPEND) {
- trace_xfs_end_io_direct_write_append(ip, offset, size);
-
- error = xfs_setfilesize(ip, offset, size);
- }
-
- return error;
-}
-
STATIC ssize_t
xfs_vm_direct_IO(
struct kiocb *iocb,
@@ -1566,7 +1309,6 @@ xfs_vm_bmap(
struct xfs_inode *ip = XFS_I(inode);
trace_xfs_vm_bmap(XFS_I(inode));
- xfs_ilock(ip, XFS_IOLOCK_SHARED);
/*
* The swap code (ab-)uses ->bmap to get a block mapping and then
@@ -1574,12 +1316,10 @@ xfs_vm_bmap(
* that on reflinks inodes, so we have to skip out here. And yes,
* 0 is the magic code for a bmap error..
*/
- if (xfs_is_reflink_inode(ip)) {
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ if (xfs_is_reflink_inode(ip))
return 0;
- }
+
filemap_write_and_wait(mapping);
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return generic_block_bmap(mapping, block, xfs_get_blocks);
}
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index 34dc00dfb91d..cc174ec6c2fd 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -55,12 +55,6 @@ struct xfs_ioend {
extern const struct address_space_operations xfs_address_space_operations;
-int xfs_get_blocks(struct inode *inode, sector_t offset,
- struct buffer_head *map_bh, int create);
-int xfs_get_blocks_direct(struct inode *inode, sector_t offset,
- struct buffer_head *map_bh, int create);
-int xfs_end_io_direct_write(struct kiocb *iocb, loff_t offset,
- ssize_t size, void *private);
int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
extern void xfs_count_page_state(struct page *, int *, int *);
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index e3da5d448bcf..d14691aa02b4 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -112,8 +112,8 @@ typedef struct attrlist_cursor_kern {
*========================================================================*/
-/* Return 0 on success, or -errno; other state communicated via *context */
-typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int,
+/* void; state communicated via *context */
+typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
unsigned char *, int, int);
typedef struct xfs_attr_list_context {
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 25e76cd6c053..97c45b6eb91e 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -74,7 +74,6 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
xfs_attr_sf_entry_t *sfe;
xfs_inode_t *dp;
int sbsize, nsbuf, count, i;
- int error;
ASSERT(context != NULL);
dp = context->dp;
@@ -102,13 +101,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
(XFS_ISRESET_CURSOR(cursor) &&
(dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
- error = context->put_listent(context,
- sfe->flags,
- sfe->nameval,
- (int)sfe->namelen,
- (int)sfe->valuelen);
- if (error)
- return error;
+ context->put_listent(context,
+ sfe->flags,
+ sfe->nameval,
+ (int)sfe->namelen,
+ (int)sfe->valuelen);
/*
* Either search callback finished early or
* didn't fit it all in the buffer after all.
@@ -193,15 +190,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
cursor->hashval = sbp->hash;
cursor->offset = 0;
}
- error = context->put_listent(context,
- sbp->flags,
- sbp->name,
- sbp->namelen,
- sbp->valuelen);
- if (error) {
- kmem_free(sbuf);
- return error;
- }
+ context->put_listent(context,
+ sbp->flags,
+ sbp->name,
+ sbp->namelen,
+ sbp->valuelen);
if (context->seen_enough)
break;
cursor->offset++;
@@ -335,11 +328,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
*/
for (;;) {
leaf = bp->b_addr;
- error = xfs_attr3_leaf_list_int(bp, context);
- if (error) {
- xfs_trans_brelse(NULL, bp);
- return error;
- }
+ xfs_attr3_leaf_list_int(bp, context);
xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
if (context->seen_enough || leafhdr.forw == 0)
break;
@@ -356,7 +345,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
/*
* Copy out attribute list entries for attr_list(), for leaf attribute lists.
*/
-int
+void
xfs_attr3_leaf_list_int(
struct xfs_buf *bp,
struct xfs_attr_list_context *context)
@@ -366,7 +355,6 @@ xfs_attr3_leaf_list_int(
struct xfs_attr3_icleaf_hdr ichdr;
struct xfs_attr_leaf_entry *entries;
struct xfs_attr_leaf_entry *entry;
- int retval;
int i;
struct xfs_mount *mp = context->dp->i_mount;
@@ -399,7 +387,7 @@ xfs_attr3_leaf_list_int(
}
if (i == ichdr.count) {
trace_xfs_attr_list_notfound(context);
- return 0;
+ return;
}
} else {
entry = &entries[0];
@@ -410,7 +398,6 @@ xfs_attr3_leaf_list_int(
/*
* We have found our place, start copying out the new attributes.
*/
- retval = 0;
for (; i < ichdr.count; entry++, i++) {
char *name;
int namelen, valuelen;
@@ -439,16 +426,14 @@ xfs_attr3_leaf_list_int(
valuelen = be32_to_cpu(name_rmt->valuelen);
}
- retval = context->put_listent(context, entry->flags,
+ context->put_listent(context, entry->flags,
name, namelen, valuelen);
- if (retval)
- break;
if (context->seen_enough)
break;
cursor->offset++;
}
trace_xfs_attr_list_leaf_end(context);
- return retval;
+ return;
}
/*
@@ -467,9 +452,9 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
if (error)
return error;
- error = xfs_attr3_leaf_list_int(bp, context);
+ xfs_attr3_leaf_list_int(bp, context);
xfs_trans_brelse(NULL, bp);
- return error;
+ return 0;
}
int
@@ -513,7 +498,7 @@ xfs_attr_list_int(
* Take care to check values and protect against them changing later,
* we may be reading them directly out of a user buffer.
*/
-STATIC int
+STATIC void
xfs_attr_put_listent(
xfs_attr_list_context_t *context,
int flags,
@@ -536,10 +521,10 @@ xfs_attr_put_listent(
*/
if (((context->flags & ATTR_SECURE) == 0) !=
((flags & XFS_ATTR_SECURE) == 0))
- return 0;
+ return;
if (((context->flags & ATTR_ROOT) == 0) !=
((flags & XFS_ATTR_ROOT) == 0))
- return 0;
+ return;
arraytop = sizeof(*alist) +
context->count * sizeof(alist->al_offset[0]);
@@ -548,7 +533,7 @@ xfs_attr_put_listent(
trace_xfs_attr_list_full(context);
alist->al_more = 1;
context->seen_enough = 1;
- return 0;
+ return;
}
aep = (attrlist_ent_t *)&context->alist[context->firstu];
@@ -558,7 +543,7 @@ xfs_attr_put_listent(
alist->al_offset[context->count++] = context->firstu;
alist->al_count = context->count;
trace_xfs_attr_list_add(context);
- return 0;
+ return;
}
/*
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 552465e011ec..b9abce524c33 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -359,9 +359,7 @@ xfs_bmap_count_blocks(
mp = ip->i_mount;
ifp = XFS_IFORK_PTR(ip, whichfork);
if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
- xfs_bmap_count_leaves(ifp, 0,
- ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
- count);
+ xfs_bmap_count_leaves(ifp, 0, xfs_iext_count(ifp), count);
return 0;
}
@@ -426,7 +424,7 @@ xfs_getbmapx_fix_eof_hole(
ifp = XFS_IFORK_PTR(ip, whichfork);
if (!moretocome &&
xfs_iext_bno_to_ext(ifp, fileblock, &lastx) &&
- (lastx == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))-1))
+ (lastx == xfs_iext_count(ifp) - 1))
out->bmv_oflags |= BMV_OF_LAST;
}
@@ -1792,6 +1790,7 @@ xfs_swap_extent_forks(
struct xfs_ifork tempifp, *ifp, *tifp;
int aforkblks = 0;
int taforkblks = 0;
+ xfs_extnum_t nextents;
__uint64_t tmp;
int error;
@@ -1877,14 +1876,13 @@ xfs_swap_extent_forks(
switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS:
- /* If the extents fit in the inode, fix the
- * pointer. Otherwise it's already NULL or
- * pointing to the extent.
+ /*
+ * If the extents fit in the inode, fix the pointer. Otherwise
+ * it's already NULL or pointing to the extent.
*/
- if (ip->i_d.di_nextents <= XFS_INLINE_EXTS) {
- ifp->if_u1.if_extents =
- ifp->if_u2.if_inline_ext;
- }
+ nextents = xfs_iext_count(&ip->i_df);
+ if (nextents <= XFS_INLINE_EXTS)
+ ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
(*src_log_flags) |= XFS_ILOG_DEXT;
break;
case XFS_DINODE_FMT_BTREE:
@@ -1896,14 +1894,13 @@ xfs_swap_extent_forks(
switch (tip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS:
- /* If the extents fit in the inode, fix the
- * pointer. Otherwise it's already NULL or
- * pointing to the extent.
+ /*
+ * If the extents fit in the inode, fix the pointer. Otherwise
+ * it's already NULL or pointing to the extent.
*/
- if (tip->i_d.di_nextents <= XFS_INLINE_EXTS) {
- tifp->if_u1.if_extents =
- tifp->if_u2.if_inline_ext;
- }
+ nextents = xfs_iext_count(&tip->i_df);
+ if (nextents <= XFS_INLINE_EXTS)
+ tifp->if_u1.if_extents = tifp->if_u2.if_inline_ext;
(*target_log_flags) |= XFS_ILOG_DEXT;
break;
case XFS_DINODE_FMT_BTREE:
@@ -1938,8 +1935,8 @@ xfs_swap_extents(
* page cache safely. Once we have done this we can take the ilocks and
* do the rest of the checks.
*/
- lock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
- xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
+ lock_two_nondirectories(VFS_I(ip), VFS_I(tip));
+ lock_flags = XFS_MMAPLOCK_EXCL;
xfs_lock_two_inodes(ip, tip, XFS_MMAPLOCK_EXCL);
/* Verify that both files have the same format */
@@ -2079,15 +2076,13 @@ xfs_swap_extents(
trace_xfs_swap_extent_after(ip, 0);
trace_xfs_swap_extent_after(tip, 1);
+out_unlock:
xfs_iunlock(ip, lock_flags);
xfs_iunlock(tip, lock_flags);
+ unlock_two_nondirectories(VFS_I(ip), VFS_I(tip));
return error;
out_trans_cancel:
xfs_trans_cancel(tp);
-
-out_unlock:
- xfs_iunlock(ip, lock_flags);
- xfs_iunlock(tip, lock_flags);
- return error;
+ goto out_unlock;
}
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 33c435f3316c..7f0a01f7b592 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -219,7 +219,6 @@ _xfs_buf_alloc(
init_completion(&bp->b_iowait);
INIT_LIST_HEAD(&bp->b_lru);
INIT_LIST_HEAD(&bp->b_list);
- RB_CLEAR_NODE(&bp->b_rbnode);
sema_init(&bp->b_sema, 0); /* held, no waiters */
spin_lock_init(&bp->b_lock);
XB_SET_OWNER(bp);
@@ -473,6 +472,62 @@ _xfs_buf_map_pages(
/*
* Finding and Reading Buffers
*/
+static int
+_xfs_buf_obj_cmp(
+ struct rhashtable_compare_arg *arg,
+ const void *obj)
+{
+ const struct xfs_buf_map *map = arg->key;
+ const struct xfs_buf *bp = obj;
+
+ /*
+ * The key hashing in the lookup path depends on the key being the
+ * first element of the compare_arg, make sure to assert this.
+ */
+ BUILD_BUG_ON(offsetof(struct xfs_buf_map, bm_bn) != 0);
+
+ if (bp->b_bn != map->bm_bn)
+ return 1;
+
+ if (unlikely(bp->b_length != map->bm_len)) {
+ /*
+ * found a block number match. If the range doesn't
+ * match, the only way this is allowed is if the buffer
+ * in the cache is stale and the transaction that made
+ * it stale has not yet committed. i.e. we are
+ * reallocating a busy extent. Skip this buffer and
+ * continue searching for an exact match.
+ */
+ ASSERT(bp->b_flags & XBF_STALE);
+ return 1;
+ }
+ return 0;
+}
+
+static const struct rhashtable_params xfs_buf_hash_params = {
+ .min_size = 32, /* empty AGs have minimal footprint */
+ .nelem_hint = 16,
+ .key_len = sizeof(xfs_daddr_t),
+ .key_offset = offsetof(struct xfs_buf, b_bn),
+ .head_offset = offsetof(struct xfs_buf, b_rhash_head),
+ .automatic_shrinking = true,
+ .obj_cmpfn = _xfs_buf_obj_cmp,
+};
+
+int
+xfs_buf_hash_init(
+ struct xfs_perag *pag)
+{
+ spin_lock_init(&pag->pag_buf_lock);
+ return rhashtable_init(&pag->pag_buf_hash, &xfs_buf_hash_params);
+}
+
+void
+xfs_buf_hash_destroy(
+ struct xfs_perag *pag)
+{
+ rhashtable_destroy(&pag->pag_buf_hash);
+}
/*
* Look up, and creates if absent, a lockable buffer for
@@ -488,27 +543,24 @@ _xfs_buf_find(
xfs_buf_t *new_bp)
{
struct xfs_perag *pag;
- struct rb_node **rbp;
- struct rb_node *parent;
xfs_buf_t *bp;
- xfs_daddr_t blkno = map[0].bm_bn;
+ struct xfs_buf_map cmap = { .bm_bn = map[0].bm_bn };
xfs_daddr_t eofs;
- int numblks = 0;
int i;
for (i = 0; i < nmaps; i++)
- numblks += map[i].bm_len;
+ cmap.bm_len += map[i].bm_len;
/* Check for IOs smaller than the sector size / not sector aligned */
- ASSERT(!(BBTOB(numblks) < btp->bt_meta_sectorsize));
- ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_meta_sectormask));
+ ASSERT(!(BBTOB(cmap.bm_len) < btp->bt_meta_sectorsize));
+ ASSERT(!(BBTOB(cmap.bm_bn) & (xfs_off_t)btp->bt_meta_sectormask));
/*
* Corrupted block numbers can get through to here, unfortunately, so we
* have to check that the buffer falls within the filesystem bounds.
*/
eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
- if (blkno < 0 || blkno >= eofs) {
+ if (cmap.bm_bn < 0 || cmap.bm_bn >= eofs) {
/*
* XXX (dgc): we should really be returning -EFSCORRUPTED here,
* but none of the higher level infrastructure supports
@@ -516,53 +568,29 @@ _xfs_buf_find(
*/
xfs_alert(btp->bt_mount,
"%s: Block out of range: block 0x%llx, EOFS 0x%llx ",
- __func__, blkno, eofs);
+ __func__, cmap.bm_bn, eofs);
WARN_ON(1);
return NULL;
}
- /* get tree root */
pag = xfs_perag_get(btp->bt_mount,
- xfs_daddr_to_agno(btp->bt_mount, blkno));
+ xfs_daddr_to_agno(btp->bt_mount, cmap.bm_bn));
- /* walk tree */
spin_lock(&pag->pag_buf_lock);
- rbp = &pag->pag_buf_tree.rb_node;
- parent = NULL;
- bp = NULL;
- while (*rbp) {
- parent = *rbp;
- bp = rb_entry(parent, struct xfs_buf, b_rbnode);
-
- if (blkno < bp->b_bn)
- rbp = &(*rbp)->rb_left;
- else if (blkno > bp->b_bn)
- rbp = &(*rbp)->rb_right;
- else {
- /*
- * found a block number match. If the range doesn't
- * match, the only way this is allowed is if the buffer
- * in the cache is stale and the transaction that made
- * it stale has not yet committed. i.e. we are
- * reallocating a busy extent. Skip this buffer and
- * continue searching to the right for an exact match.
- */
- if (bp->b_length != numblks) {
- ASSERT(bp->b_flags & XBF_STALE);
- rbp = &(*rbp)->rb_right;
- continue;
- }
- atomic_inc(&bp->b_hold);
- goto found;
- }
+ bp = rhashtable_lookup_fast(&pag->pag_buf_hash, &cmap,
+ xfs_buf_hash_params);
+ if (bp) {
+ atomic_inc(&bp->b_hold);
+ goto found;
}
/* No match found */
if (new_bp) {
- rb_link_node(&new_bp->b_rbnode, parent, rbp);
- rb_insert_color(&new_bp->b_rbnode, &pag->pag_buf_tree);
/* the buffer keeps the perag reference until it is freed */
new_bp->b_pag = pag;
+ rhashtable_insert_fast(&pag->pag_buf_hash,
+ &new_bp->b_rhash_head,
+ xfs_buf_hash_params);
spin_unlock(&pag->pag_buf_lock);
} else {
XFS_STATS_INC(btp->bt_mount, xb_miss_locked);
@@ -930,7 +958,6 @@ xfs_buf_rele(
if (!pag) {
ASSERT(list_empty(&bp->b_lru));
- ASSERT(RB_EMPTY_NODE(&bp->b_rbnode));
if (atomic_dec_and_test(&bp->b_hold)) {
xfs_buf_ioacct_dec(bp);
xfs_buf_free(bp);
@@ -938,8 +965,6 @@ xfs_buf_rele(
return;
}
- ASSERT(!RB_EMPTY_NODE(&bp->b_rbnode));
-
ASSERT(atomic_read(&bp->b_hold) > 0);
release = atomic_dec_and_lock(&bp->b_hold, &pag->pag_buf_lock);
@@ -983,7 +1008,8 @@ xfs_buf_rele(
}
ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));
- rb_erase(&bp->b_rbnode, &pag->pag_buf_tree);
+ rhashtable_remove_fast(&pag->pag_buf_hash, &bp->b_rhash_head,
+ xfs_buf_hash_params);
spin_unlock(&pag->pag_buf_lock);
xfs_perag_put(pag);
freebuf = true;
@@ -1711,8 +1737,7 @@ xfs_free_buftarg(
percpu_counter_destroy(&btp->bt_io_count);
list_lru_destroy(&btp->bt_lru);
- if (mp->m_flags & XFS_MOUNT_BARRIER)
- xfs_blkdev_issue_flush(btp);
+ xfs_blkdev_issue_flush(btp);
kmem_free(btp);
}
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 1c2e52b2d926..8a9d3a9599f0 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -71,6 +71,7 @@ typedef unsigned int xfs_buf_flags_t;
{ XBF_READ, "READ" }, \
{ XBF_WRITE, "WRITE" }, \
{ XBF_READ_AHEAD, "READ_AHEAD" }, \
+ { XBF_NO_IOACCT, "NO_IOACCT" }, \
{ XBF_ASYNC, "ASYNC" }, \
{ XBF_DONE, "DONE" }, \
{ XBF_STALE, "STALE" }, \
@@ -150,7 +151,7 @@ typedef struct xfs_buf {
* which is the only bit that is touched if we hit the semaphore
* fast-path on locking.
*/
- struct rb_node b_rbnode; /* rbtree node */
+ struct rhash_head b_rhash_head; /* pag buffer hash node */
xfs_daddr_t b_bn; /* block number of buffer */
int b_length; /* size of buffer in BBs */
atomic_t b_hold; /* reference count */
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 29816981b50a..003a99b83bd8 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -677,7 +677,6 @@ xfs_readdir(
args.dp = dp;
args.geo = dp->i_mount->m_dir_geo;
- xfs_ilock(dp, XFS_IOLOCK_SHARED);
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_getdents(&args, ctx);
else if ((rval = xfs_dir2_isblock(&args, &v)))
@@ -686,7 +685,6 @@ xfs_readdir(
rval = xfs_dir2_block_getdents(&args, ctx);
else
rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
- xfs_iunlock(dp, XFS_IOLOCK_SHARED);
return rval;
}
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index d818c160451f..65d27a502909 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -48,40 +48,6 @@
static const struct vm_operations_struct xfs_file_vm_ops;
/*
- * Locking primitives for read and write IO paths to ensure we consistently use
- * and order the inode->i_mutex, ip->i_lock and ip->i_iolock.
- */
-static inline void
-xfs_rw_ilock(
- struct xfs_inode *ip,
- int type)
-{
- if (type & XFS_IOLOCK_EXCL)
- inode_lock(VFS_I(ip));
- xfs_ilock(ip, type);
-}
-
-static inline void
-xfs_rw_iunlock(
- struct xfs_inode *ip,
- int type)
-{
- xfs_iunlock(ip, type);
- if (type & XFS_IOLOCK_EXCL)
- inode_unlock(VFS_I(ip));
-}
-
-static inline void
-xfs_rw_ilock_demote(
- struct xfs_inode *ip,
- int type)
-{
- xfs_ilock_demote(ip, type);
- if (type & XFS_IOLOCK_EXCL)
- inode_unlock(VFS_I(ip));
-}
-
-/*
* Clear the specified ranges to zero through either the pagecache or DAX.
* Holes and unwritten extents will be left as-is as they already are zeroed.
*/
@@ -183,19 +149,16 @@ xfs_file_fsync(
xfs_iflags_clear(ip, XFS_ITRUNCATED);
- if (mp->m_flags & XFS_MOUNT_BARRIER) {
- /*
- * If we have an RT and/or log subvolume we need to make sure
- * to flush the write cache the device used for file data
- * first. This is to ensure newly written file data make
- * it to disk before logging the new inode size in case of
- * an extending write.
- */
- if (XFS_IS_REALTIME_INODE(ip))
- xfs_blkdev_issue_flush(mp->m_rtdev_targp);
- else if (mp->m_logdev_targp != mp->m_ddev_targp)
- xfs_blkdev_issue_flush(mp->m_ddev_targp);
- }
+ /*
+ * If we have an RT and/or log subvolume we need to make sure to flush
+ * the write cache the device used for file data first. This is to
+ * ensure newly written file data make it to disk before logging the new
+ * inode size in case of an extending write.
+ */
+ if (XFS_IS_REALTIME_INODE(ip))
+ xfs_blkdev_issue_flush(mp->m_rtdev_targp);
+ else if (mp->m_logdev_targp != mp->m_ddev_targp)
+ xfs_blkdev_issue_flush(mp->m_ddev_targp);
/*
* All metadata updates are logged, which means that we just have to
@@ -230,10 +193,8 @@ xfs_file_fsync(
* an already allocated file and thus do not have any metadata to
* commit.
*/
- if ((mp->m_flags & XFS_MOUNT_BARRIER) &&
- mp->m_logdev_targp == mp->m_ddev_targp &&
- !XFS_IS_REALTIME_INODE(ip) &&
- !log_flushed)
+ if (!log_flushed && !XFS_IS_REALTIME_INODE(ip) &&
+ mp->m_logdev_targp == mp->m_ddev_targp)
xfs_blkdev_issue_flush(mp->m_ddev_targp);
return error;
@@ -244,62 +205,21 @@ xfs_file_dio_aio_read(
struct kiocb *iocb,
struct iov_iter *to)
{
- struct address_space *mapping = iocb->ki_filp->f_mapping;
- struct inode *inode = mapping->host;
- struct xfs_inode *ip = XFS_I(inode);
- loff_t isize = i_size_read(inode);
+ struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp));
size_t count = iov_iter_count(to);
- loff_t end = iocb->ki_pos + count - 1;
- struct iov_iter data;
- struct xfs_buftarg *target;
- ssize_t ret = 0;
+ ssize_t ret;
trace_xfs_file_direct_read(ip, count, iocb->ki_pos);
if (!count)
return 0; /* skip atime */
- if (XFS_IS_REALTIME_INODE(ip))
- target = ip->i_mount->m_rtdev_targp;
- else
- target = ip->i_mount->m_ddev_targp;
-
- /* DIO must be aligned to device logical sector size */
- if ((iocb->ki_pos | count) & target->bt_logical_sectormask) {
- if (iocb->ki_pos == isize)
- return 0;
- return -EINVAL;
- }
-
file_accessed(iocb->ki_filp);
- xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
- if (mapping->nrpages) {
- ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, end);
- if (ret)
- goto out_unlock;
-
- /*
- * Invalidate whole pages. This can return an error if we fail
- * to invalidate a page, but this should never happen on XFS.
- * Warn if it does fail.
- */
- ret = invalidate_inode_pages2_range(mapping,
- iocb->ki_pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
- WARN_ON_ONCE(ret);
- ret = 0;
- }
+ xfs_ilock(ip, XFS_IOLOCK_SHARED);
+ ret = iomap_dio_rw(iocb, to, &xfs_iomap_ops, NULL);
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- data = *to;
- ret = __blockdev_direct_IO(iocb, inode, target->bt_bdev, &data,
- xfs_get_blocks_direct, NULL, NULL, 0);
- if (ret >= 0) {
- iocb->ki_pos += ret;
- iov_iter_advance(to, ret);
- }
-
-out_unlock:
- xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
return ret;
}
@@ -317,9 +237,9 @@ xfs_file_dax_read(
if (!count)
return 0; /* skip atime */
- xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+ xfs_ilock(ip, XFS_IOLOCK_SHARED);
ret = dax_iomap_rw(iocb, to, &xfs_iomap_ops);
- xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
file_accessed(iocb->ki_filp);
return ret;
@@ -335,9 +255,9 @@ xfs_file_buffered_aio_read(
trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos);
- xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+ xfs_ilock(ip, XFS_IOLOCK_SHARED);
ret = generic_file_read_iter(iocb, to);
- xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return ret;
}
@@ -418,15 +338,18 @@ restart:
if (error <= 0)
return error;
- error = xfs_break_layouts(inode, iolock, true);
+ error = xfs_break_layouts(inode, iolock);
if (error)
return error;
- /* For changing security info in file_remove_privs() we need i_mutex */
+ /*
+ * For changing security info in file_remove_privs() we need i_rwsem
+ * exclusively.
+ */
if (*iolock == XFS_IOLOCK_SHARED && !IS_NOSEC(inode)) {
- xfs_rw_iunlock(ip, *iolock);
+ xfs_iunlock(ip, *iolock);
*iolock = XFS_IOLOCK_EXCL;
- xfs_rw_ilock(ip, *iolock);
+ xfs_ilock(ip, *iolock);
goto restart;
}
/*
@@ -451,9 +374,9 @@ restart:
spin_unlock(&ip->i_flags_lock);
if (!drained_dio) {
if (*iolock == XFS_IOLOCK_SHARED) {
- xfs_rw_iunlock(ip, *iolock);
+ xfs_iunlock(ip, *iolock);
*iolock = XFS_IOLOCK_EXCL;
- xfs_rw_ilock(ip, *iolock);
+ xfs_ilock(ip, *iolock);
iov_iter_reexpand(from, count);
}
/*
@@ -496,6 +419,58 @@ restart:
return 0;
}
+static int
+xfs_dio_write_end_io(
+ struct kiocb *iocb,
+ ssize_t size,
+ unsigned flags)
+{
+ struct inode *inode = file_inode(iocb->ki_filp);
+ struct xfs_inode *ip = XFS_I(inode);
+ loff_t offset = iocb->ki_pos;
+ bool update_size = false;
+ int error = 0;
+
+ trace_xfs_end_io_direct_write(ip, offset, size);
+
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ return -EIO;
+
+ if (size <= 0)
+ return size;
+
+ /*
+ * We need to update the in-core inode size here so that we don't end up
+ * with the on-disk inode size being outside the in-core inode size. We
+ * have no other method of updating EOF for AIO, so always do it here
+ * if necessary.
+ *
+ * We need to lock the test/set EOF update as we can be racing with
+ * other IO completions here to update the EOF. Failing to serialise
+ * here can result in EOF moving backwards and Bad Things Happen when
+ * that occurs.
+ */
+ spin_lock(&ip->i_flags_lock);
+ if (offset + size > i_size_read(inode)) {
+ i_size_write(inode, offset + size);
+ update_size = true;
+ }
+ spin_unlock(&ip->i_flags_lock);
+
+ if (flags & IOMAP_DIO_COW) {
+ error = xfs_reflink_end_cow(ip, offset, size);
+ if (error)
+ return error;
+ }
+
+ if (flags & IOMAP_DIO_UNWRITTEN)
+ error = xfs_iomap_write_unwritten(ip, offset, size);
+ else if (update_size)
+ error = xfs_setfilesize(ip, offset, size);
+
+ return error;
+}
+
/*
* xfs_file_dio_aio_write - handle direct IO writes
*
@@ -535,9 +510,7 @@ xfs_file_dio_aio_write(
int unaligned_io = 0;
int iolock;
size_t count = iov_iter_count(from);
- loff_t end;
- struct iov_iter data;
- struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ?
+ struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
/* DIO must be aligned to device logical sector size */
@@ -559,29 +532,12 @@ xfs_file_dio_aio_write(
iolock = XFS_IOLOCK_SHARED;
}
- xfs_rw_ilock(ip, iolock);
+ xfs_ilock(ip, iolock);
ret = xfs_file_aio_write_checks(iocb, from, &iolock);
if (ret)
goto out;
count = iov_iter_count(from);
- end = iocb->ki_pos + count - 1;
-
- if (mapping->nrpages) {
- ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, end);
- if (ret)
- goto out;
-
- /*
- * Invalidate whole pages. This can return an error if we fail
- * to invalidate a page, but this should never happen on XFS.
- * Warn if it does fail.
- */
- ret = invalidate_inode_pages2_range(mapping,
- iocb->ki_pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
- WARN_ON_ONCE(ret);
- ret = 0;
- }
/*
* If we are doing unaligned IO, wait for all other IO to drain,
@@ -591,7 +547,7 @@ xfs_file_dio_aio_write(
if (unaligned_io)
inode_dio_wait(inode);
else if (iolock == XFS_IOLOCK_EXCL) {
- xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
+ xfs_ilock_demote(ip, XFS_IOLOCK_EXCL);
iolock = XFS_IOLOCK_SHARED;
}
@@ -604,24 +560,9 @@ xfs_file_dio_aio_write(
goto out;
}
- data = *from;
- ret = __blockdev_direct_IO(iocb, inode, target->bt_bdev, &data,
- xfs_get_blocks_direct, xfs_end_io_direct_write,
- NULL, DIO_ASYNC_EXTEND);
-
- /* see generic_file_direct_write() for why this is necessary */
- if (mapping->nrpages) {
- invalidate_inode_pages2_range(mapping,
- iocb->ki_pos >> PAGE_SHIFT,
- end >> PAGE_SHIFT);
- }
-
- if (ret > 0) {
- iocb->ki_pos += ret;
- iov_iter_advance(from, ret);
- }
+ ret = iomap_dio_rw(iocb, from, &xfs_iomap_ops, xfs_dio_write_end_io);
out:
- xfs_rw_iunlock(ip, iolock);
+ xfs_iunlock(ip, iolock);
/*
* No fallback to buffered IO on errors for XFS, direct IO will either
@@ -643,7 +584,7 @@ xfs_file_dax_write(
size_t count;
loff_t pos;
- xfs_rw_ilock(ip, iolock);
+ xfs_ilock(ip, iolock);
ret = xfs_file_aio_write_checks(iocb, from, &iolock);
if (ret)
goto out;
@@ -652,15 +593,13 @@ xfs_file_dax_write(
count = iov_iter_count(from);
trace_xfs_file_dax_write(ip, count, pos);
-
ret = dax_iomap_rw(iocb, from, &xfs_iomap_ops);
if (ret > 0 && iocb->ki_pos > i_size_read(inode)) {
i_size_write(inode, iocb->ki_pos);
error = xfs_setfilesize(ip, pos, ret);
}
-
out:
- xfs_rw_iunlock(ip, iolock);
+ xfs_iunlock(ip, iolock);
return error ? error : ret;
}
@@ -677,7 +616,7 @@ xfs_file_buffered_aio_write(
int enospc = 0;
int iolock = XFS_IOLOCK_EXCL;
- xfs_rw_ilock(ip, iolock);
+ xfs_ilock(ip, iolock);
ret = xfs_file_aio_write_checks(iocb, from, &iolock);
if (ret)
@@ -721,7 +660,7 @@ write_retry:
current->backing_dev_info = NULL;
out:
- xfs_rw_iunlock(ip, iolock);
+ xfs_iunlock(ip, iolock);
return ret;
}
@@ -797,7 +736,7 @@ xfs_file_fallocate(
return -EOPNOTSUPP;
xfs_ilock(ip, iolock);
- error = xfs_break_layouts(inode, &iolock, false);
+ error = xfs_break_layouts(inode, &iolock);
if (error)
goto out_unlock;
@@ -939,7 +878,6 @@ xfs_file_clone_range(
len, false);
}
-#define XFS_MAX_DEDUPE_LEN (16 * 1024 * 1024)
STATIC ssize_t
xfs_file_dedupe_range(
struct file *src_file,
@@ -950,14 +888,6 @@ xfs_file_dedupe_range(
{
int error;
- /*
- * Limit the total length we will dedupe for each operation.
- * This is intended to bound the total time spent in this
- * ioctl to something sane.
- */
- if (len > XFS_MAX_DEDUPE_LEN)
- len = XFS_MAX_DEDUPE_LEN;
-
error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff,
len, true);
if (error)
@@ -1501,15 +1431,9 @@ xfs_filemap_fault(
return xfs_filemap_page_mkwrite(vma, vmf);
xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
- if (IS_DAX(inode)) {
- /*
- * we do not want to trigger unwritten extent conversion on read
- * faults - that is unnecessary overhead and would also require
- * changes to xfs_get_blocks_direct() to map unwritten extent
- * ioend for conversion on read-only mappings.
- */
+ if (IS_DAX(inode))
ret = dax_iomap_fault(vma, vmf, &xfs_iomap_ops);
- } else
+ else
ret = filemap_fault(vma, vmf);
xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index f295049db681..ff4d6311c7f4 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -70,8 +70,6 @@ xfs_inode_alloc(
ASSERT(!xfs_isiflocked(ip));
ASSERT(ip->i_ino == 0);
- mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
-
/* initialise the xfs inode */
ip->i_ino = ino;
ip->i_mount = mp;
@@ -123,7 +121,6 @@ __xfs_inode_free(
{
/* asserts to verify all state is correct here */
ASSERT(atomic_read(&ip->i_pincount) == 0);
- ASSERT(!xfs_isiflocked(ip));
XFS_STATS_DEC(ip->i_mount, vn_active);
call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
@@ -133,6 +130,8 @@ void
xfs_inode_free(
struct xfs_inode *ip)
{
+ ASSERT(!xfs_isiflocked(ip));
+
/*
* Because we use RCU freeing we need to ensure the inode always
* appears to be reclaimed with an invalid inode number when in the
@@ -393,8 +392,8 @@ xfs_iget_cache_hit(
xfs_inode_clear_reclaim_tag(pag, ip->i_ino);
inode->i_state = I_NEW;
- ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
- mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
+ ASSERT(!rwsem_is_locked(&inode->i_rwsem));
+ init_rwsem(&inode->i_rwsem);
spin_unlock(&ip->i_flags_lock);
spin_unlock(&pag->pag_ici_lock);
@@ -981,6 +980,7 @@ restart:
if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
xfs_iunpin_wait(ip);
+ /* xfs_iflush_abort() drops the flush lock */
xfs_iflush_abort(ip, false);
goto reclaim;
}
@@ -989,10 +989,10 @@ restart:
goto out_ifunlock;
xfs_iunpin_wait(ip);
}
- if (xfs_iflags_test(ip, XFS_ISTALE))
- goto reclaim;
- if (xfs_inode_clean(ip))
+ if (xfs_iflags_test(ip, XFS_ISTALE) || xfs_inode_clean(ip)) {
+ xfs_ifunlock(ip);
goto reclaim;
+ }
/*
* Never flush out dirty data during non-blocking reclaim, as it would
@@ -1030,25 +1030,24 @@ restart:
xfs_buf_relse(bp);
}
- xfs_iflock(ip);
reclaim:
+ ASSERT(!xfs_isiflocked(ip));
+
/*
* Because we use RCU freeing we need to ensure the inode always appears
* to be reclaimed with an invalid inode number when in the free state.
- * We do this as early as possible under the ILOCK and flush lock so
- * that xfs_iflush_cluster() can be guaranteed to detect races with us
- * here. By doing this, we guarantee that once xfs_iflush_cluster has
- * locked both the XFS_ILOCK and the flush lock that it will see either
- * a valid, flushable inode that will serialise correctly against the
- * locks below, or it will see a clean (and invalid) inode that it can
- * skip.
+ * We do this as early as possible under the ILOCK so that
+ * xfs_iflush_cluster() can be guaranteed to detect races with us here.
+ * By doing this, we guarantee that once xfs_iflush_cluster has locked
+ * XFS_ILOCK that it will see either a valid, flushable inode that will
+ * serialise correctly, or it will see a clean (and invalid) inode that
+ * it can skip.
*/
spin_lock(&ip->i_flags_lock);
ip->i_flags = XFS_IRECLAIM;
ip->i_ino = 0;
spin_unlock(&ip->i_flags_lock);
- xfs_ifunlock(ip);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
XFS_STATS_INC(ip->i_mount, xs_ig_reclaims);
@@ -1580,10 +1579,15 @@ xfs_inode_free_cowblocks(
struct xfs_eofblocks *eofb = args;
bool need_iolock = true;
int match;
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
ASSERT(!eofb || (eofb && eofb->eof_scan_owner != 0));
- if (!xfs_reflink_has_real_cow_blocks(ip)) {
+ /*
+ * Just clear the tag if we have an empty cow fork or none at all. It's
+ * possible the inode was fully unshared since it was originally tagged.
+ */
+ if (!xfs_is_reflink_inode(ip) || !ifp->if_bytes) {
trace_xfs_inode_free_cowblocks_invalid(ip);
xfs_inode_clear_cowblocks_tag(ip);
return 0;
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
index d45ca72af6fb..865ad1373e5e 100644
--- a/fs/xfs/xfs_icreate_item.c
+++ b/fs/xfs/xfs_icreate_item.c
@@ -133,7 +133,7 @@ xfs_icreate_item_committing(
/*
* This is the ops vector shared by all buf log items.
*/
-static struct xfs_item_ops xfs_icreate_item_ops = {
+static const struct xfs_item_ops xfs_icreate_item_ops = {
.iop_size = xfs_icreate_item_size,
.iop_format = xfs_icreate_item_format,
.iop_pin = xfs_icreate_item_pin,
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 4e560e6a12c1..b9557795eb74 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -142,31 +142,31 @@ xfs_ilock_attr_map_shared(
}
/*
- * The xfs inode contains 3 multi-reader locks: the i_iolock the i_mmap_lock and
- * the i_lock. This routine allows various combinations of the locks to be
- * obtained.
+ * In addition to i_rwsem in the VFS inode, the xfs inode contains 2
+ * multi-reader locks: i_mmap_lock and the i_lock. This routine allows
+ * various combinations of the locks to be obtained.
*
* The 3 locks should always be ordered so that the IO lock is obtained first,
* the mmap lock second and the ilock last in order to prevent deadlock.
*
* Basic locking order:
*
- * i_iolock -> i_mmap_lock -> page_lock -> i_ilock
+ * i_rwsem -> i_mmap_lock -> page_lock -> i_ilock
*
* mmap_sem locking order:
*
- * i_iolock -> page lock -> mmap_sem
+ * i_rwsem -> page lock -> mmap_sem
* mmap_sem -> i_mmap_lock -> page_lock
*
* The difference in mmap_sem locking order mean that we cannot hold the
* i_mmap_lock over syscall based read(2)/write(2) based IO. These IO paths can
* fault in pages during copy in/out (for buffered IO) or require the mmap_sem
* in get_user_pages() to map the user pages into the kernel address space for
- * direct IO. Similarly the i_iolock cannot be taken inside a page fault because
+ * direct IO. Similarly the i_rwsem cannot be taken inside a page fault because
* page faults already hold the mmap_sem.
*
* Hence to serialise fully against both syscall and mmap based IO, we need to
- * take both the i_iolock and the i_mmap_lock. These locks should *only* be both
+ * take both the i_rwsem and the i_mmap_lock. These locks should *only* be both
* taken in places where we need to invalidate the page cache in a race
* free manner (e.g. truncate, hole punch and other extent manipulation
* functions).
@@ -191,10 +191,13 @@ xfs_ilock(
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_SUBCLASS_MASK)) == 0);
- if (lock_flags & XFS_IOLOCK_EXCL)
- mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
- else if (lock_flags & XFS_IOLOCK_SHARED)
- mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
+ if (lock_flags & XFS_IOLOCK_EXCL) {
+ down_write_nested(&VFS_I(ip)->i_rwsem,
+ XFS_IOLOCK_DEP(lock_flags));
+ } else if (lock_flags & XFS_IOLOCK_SHARED) {
+ down_read_nested(&VFS_I(ip)->i_rwsem,
+ XFS_IOLOCK_DEP(lock_flags));
+ }
if (lock_flags & XFS_MMAPLOCK_EXCL)
mrupdate_nested(&ip->i_mmaplock, XFS_MMAPLOCK_DEP(lock_flags));
@@ -240,10 +243,10 @@ xfs_ilock_nowait(
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_SUBCLASS_MASK)) == 0);
if (lock_flags & XFS_IOLOCK_EXCL) {
- if (!mrtryupdate(&ip->i_iolock))
+ if (!down_write_trylock(&VFS_I(ip)->i_rwsem))
goto out;
} else if (lock_flags & XFS_IOLOCK_SHARED) {
- if (!mrtryaccess(&ip->i_iolock))
+ if (!down_read_trylock(&VFS_I(ip)->i_rwsem))
goto out;
}
@@ -271,9 +274,9 @@ out_undo_mmaplock:
mrunlock_shared(&ip->i_mmaplock);
out_undo_iolock:
if (lock_flags & XFS_IOLOCK_EXCL)
- mrunlock_excl(&ip->i_iolock);
+ up_write(&VFS_I(ip)->i_rwsem);
else if (lock_flags & XFS_IOLOCK_SHARED)
- mrunlock_shared(&ip->i_iolock);
+ up_read(&VFS_I(ip)->i_rwsem);
out:
return 0;
}
@@ -310,9 +313,9 @@ xfs_iunlock(
ASSERT(lock_flags != 0);
if (lock_flags & XFS_IOLOCK_EXCL)
- mrunlock_excl(&ip->i_iolock);
+ up_write(&VFS_I(ip)->i_rwsem);
else if (lock_flags & XFS_IOLOCK_SHARED)
- mrunlock_shared(&ip->i_iolock);
+ up_read(&VFS_I(ip)->i_rwsem);
if (lock_flags & XFS_MMAPLOCK_EXCL)
mrunlock_excl(&ip->i_mmaplock);
@@ -345,7 +348,7 @@ xfs_ilock_demote(
if (lock_flags & XFS_MMAPLOCK_EXCL)
mrdemote(&ip->i_mmaplock);
if (lock_flags & XFS_IOLOCK_EXCL)
- mrdemote(&ip->i_iolock);
+ downgrade_write(&VFS_I(ip)->i_rwsem);
trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
}
@@ -370,8 +373,9 @@ xfs_isilocked(
if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {
if (!(lock_flags & XFS_IOLOCK_SHARED))
- return !!ip->i_iolock.mr_writer;
- return rwsem_is_locked(&ip->i_iolock.mr_lock);
+ return !debug_locks ||
+ lockdep_is_held_type(&VFS_I(ip)->i_rwsem, 0);
+ return rwsem_is_locked(&VFS_I(ip)->i_rwsem);
}
ASSERT(0);
@@ -421,11 +425,7 @@ xfs_lock_inumorder(int lock_mode, int subclass)
if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) {
ASSERT(subclass <= XFS_IOLOCK_MAX_SUBCLASS);
- ASSERT(xfs_lockdep_subclass_ok(subclass +
- XFS_IOLOCK_PARENT_VAL));
class += subclass << XFS_IOLOCK_SHIFT;
- if (lock_mode & XFS_IOLOCK_PARENT)
- class += XFS_IOLOCK_PARENT_VAL << XFS_IOLOCK_SHIFT;
}
if (lock_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)) {
@@ -477,8 +477,6 @@ xfs_lock_inodes(
XFS_ILOCK_EXCL));
ASSERT(!(lock_mode & (XFS_IOLOCK_SHARED | XFS_MMAPLOCK_SHARED |
XFS_ILOCK_SHARED)));
- ASSERT(!(lock_mode & XFS_IOLOCK_EXCL) ||
- inodes <= XFS_IOLOCK_MAX_SUBCLASS + 1);
ASSERT(!(lock_mode & XFS_MMAPLOCK_EXCL) ||
inodes <= XFS_MMAPLOCK_MAX_SUBCLASS + 1);
ASSERT(!(lock_mode & XFS_ILOCK_EXCL) ||
@@ -581,10 +579,8 @@ xfs_lock_two_inodes(
int attempts = 0;
xfs_log_item_t *lp;
- if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) {
- ASSERT(!(lock_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)));
- ASSERT(!(lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)));
- } else if (lock_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL))
+ ASSERT(!(lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)));
+ if (lock_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL))
ASSERT(!(lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)));
ASSERT(ip0->i_ino != ip1->i_ino);
@@ -715,7 +711,6 @@ xfs_lookup(
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return -EIO;
- xfs_ilock(dp, XFS_IOLOCK_SHARED);
error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
if (error)
goto out_unlock;
@@ -724,14 +719,12 @@ xfs_lookup(
if (error)
goto out_free_name;
- xfs_iunlock(dp, XFS_IOLOCK_SHARED);
return 0;
out_free_name:
if (ci_name)
kmem_free(ci_name->name);
out_unlock:
- xfs_iunlock(dp, XFS_IOLOCK_SHARED);
*ipp = NULL;
return error;
}
@@ -1215,8 +1208,7 @@ xfs_create(
if (error)
goto out_release_inode;
- xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
- XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
+ xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
unlock_dp_on_error = true;
xfs_defer_init(&dfops, &first_block);
@@ -1252,7 +1244,7 @@ xfs_create(
* the transaction cancel unlocking dp so don't do it explicitly in the
* error path.
*/
- xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
unlock_dp_on_error = false;
error = xfs_dir_createname(tp, dp, name, ip->i_ino,
@@ -1325,7 +1317,7 @@ xfs_create(
xfs_qm_dqrele(pdqp);
if (unlock_dp_on_error)
- xfs_iunlock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_iunlock(dp, XFS_ILOCK_EXCL);
return error;
}
@@ -1466,11 +1458,10 @@ xfs_link(
if (error)
goto std_return;
- xfs_ilock(tdp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, tdp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
/*
* If we are using project inheritance, we only allow hard link
@@ -2041,7 +2032,6 @@ xfs_iunlink(
agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket_index);
- xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
xfs_trans_log_buf(tp, agibp, offset,
(offset + sizeof(xfs_agino_t) - 1));
return 0;
@@ -2133,7 +2123,6 @@ xfs_iunlink_remove(
agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket_index);
- xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
xfs_trans_log_buf(tp, agibp, offset,
(offset + sizeof(xfs_agino_t) - 1));
} else {
@@ -2579,10 +2568,9 @@ xfs_remove(
goto std_return;
}
- xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
/*
@@ -2963,12 +2951,6 @@ xfs_rename(
* whether the target directory is the same as the source
* directory, we can lock from 2 to 4 inodes.
*/
- if (!new_parent)
- xfs_ilock(src_dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
- else
- xfs_lock_two_inodes(src_dp, target_dp,
- XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
-
xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL);
/*
@@ -2976,9 +2958,9 @@ xfs_rename(
* we can rely on either trans_commit or trans_cancel to unlock
* them.
*/
- xfs_trans_ijoin(tp, src_dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
if (new_parent)
- xfs_trans_ijoin(tp, target_dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
if (target_ip)
xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index f14c1de2549d..10dcf27b4c85 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -56,7 +56,6 @@ typedef struct xfs_inode {
/* Transaction and locking information. */
struct xfs_inode_log_item *i_itemp; /* logging information */
mrlock_t i_lock; /* inode lock */
- mrlock_t i_iolock; /* inode IO lock */
mrlock_t i_mmaplock; /* inode mmap IO lock */
atomic_t i_pincount; /* inode pin count */
spinlock_t i_flags_lock; /* inode i_flags lock */
@@ -246,6 +245,11 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
* Synchronize processes attempting to flush the in-core inode back to disk.
*/
+static inline int xfs_isiflocked(struct xfs_inode *ip)
+{
+ return xfs_iflags_test(ip, XFS_IFLOCK);
+}
+
extern void __xfs_iflock(struct xfs_inode *ip);
static inline int xfs_iflock_nowait(struct xfs_inode *ip)
@@ -261,16 +265,12 @@ static inline void xfs_iflock(struct xfs_inode *ip)
static inline void xfs_ifunlock(struct xfs_inode *ip)
{
+ ASSERT(xfs_isiflocked(ip));
xfs_iflags_clear(ip, XFS_IFLOCK);
smp_mb();
wake_up_bit(&ip->i_flags, __XFS_IFLOCK_BIT);
}
-static inline int xfs_isiflocked(struct xfs_inode *ip)
-{
- return xfs_iflags_test(ip, XFS_IFLOCK);
-}
-
/*
* Flags for inode locking.
* Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
@@ -332,7 +332,7 @@ static inline int xfs_isiflocked(struct xfs_inode *ip)
* IOLOCK values
*
* 0-3 subclass value
- * 4-7 PARENT subclass values
+ * 4-7 unused
*
* MMAPLOCK values
*
@@ -347,10 +347,8 @@ static inline int xfs_isiflocked(struct xfs_inode *ip)
*
*/
#define XFS_IOLOCK_SHIFT 16
-#define XFS_IOLOCK_PARENT_VAL 4
-#define XFS_IOLOCK_MAX_SUBCLASS (XFS_IOLOCK_PARENT_VAL - 1)
+#define XFS_IOLOCK_MAX_SUBCLASS 3
#define XFS_IOLOCK_DEP_MASK 0x000f0000
-#define XFS_IOLOCK_PARENT (XFS_IOLOCK_PARENT_VAL << XFS_IOLOCK_SHIFT)
#define XFS_MMAPLOCK_SHIFT 20
#define XFS_MMAPLOCK_NUMORDER 0
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 9610e9c00952..d90e7811ccdd 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -164,7 +164,7 @@ xfs_inode_item_format_data_fork(
struct xfs_bmbt_rec *p;
ASSERT(ip->i_df.if_u1.if_extents != NULL);
- ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0);
+ ASSERT(xfs_iext_count(&ip->i_df) > 0);
p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK);
@@ -261,7 +261,7 @@ xfs_inode_item_format_attr_fork(
ip->i_afp->if_bytes > 0) {
struct xfs_bmbt_rec *p;
- ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) ==
+ ASSERT(xfs_iext_count(ip->i_afp) ==
ip->i_d.di_anextents);
ASSERT(ip->i_afp->if_u1.if_extents != NULL);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index c245bed3249b..fc563b82aea6 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -639,7 +639,7 @@ xfs_ioc_space(
return error;
xfs_ilock(ip, iolock);
- error = xfs_break_layouts(inode, &iolock, false);
+ error = xfs_break_layouts(inode, &iolock);
if (error)
goto out_unlock;
@@ -910,16 +910,14 @@ xfs_ioc_fsgetxattr(
if (attr) {
if (ip->i_afp) {
if (ip->i_afp->if_flags & XFS_IFEXTENTS)
- fa.fsx_nextents = ip->i_afp->if_bytes /
- sizeof(xfs_bmbt_rec_t);
+ fa.fsx_nextents = xfs_iext_count(ip->i_afp);
else
fa.fsx_nextents = ip->i_d.di_anextents;
} else
fa.fsx_nextents = 0;
} else {
if (ip->i_df.if_flags & XFS_IFEXTENTS)
- fa.fsx_nextents = ip->i_df.if_bytes /
- sizeof(xfs_bmbt_rec_t);
+ fa.fsx_nextents = xfs_iext_count(&ip->i_df);
else
fa.fsx_nextents = ip->i_d.di_nextents;
}
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 436e109bb01e..0d147428971e 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -395,11 +395,12 @@ xfs_iomap_prealloc_size(
struct xfs_inode *ip,
loff_t offset,
loff_t count,
- xfs_extnum_t idx,
- struct xfs_bmbt_irec *prev)
+ xfs_extnum_t idx)
{
struct xfs_mount *mp = ip->i_mount;
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ struct xfs_bmbt_irec prev;
int shift = 0;
int64_t freesp;
xfs_fsblock_t qblocks;
@@ -419,8 +420,8 @@ xfs_iomap_prealloc_size(
*/
if ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ||
XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) ||
- idx == 0 ||
- prev->br_startoff + prev->br_blockcount < offset_fsb)
+ !xfs_iext_get_extent(ifp, idx - 1, &prev) ||
+ prev.br_startoff + prev.br_blockcount < offset_fsb)
return mp->m_writeio_blocks;
/*
@@ -439,8 +440,8 @@ xfs_iomap_prealloc_size(
* always extends to MAXEXTLEN rather than falling short due to things
* like stripe unit/width alignment of real extents.
*/
- if (prev->br_blockcount <= (MAXEXTLEN >> 1))
- alloc_blocks = prev->br_blockcount << 1;
+ if (prev.br_blockcount <= (MAXEXTLEN >> 1))
+ alloc_blocks = prev.br_blockcount << 1;
else
alloc_blocks = XFS_B_TO_FSB(mp, offset);
if (!alloc_blocks)
@@ -535,11 +536,11 @@ xfs_file_iomap_begin_delay(
xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
xfs_fileoff_t maxbytes_fsb =
XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
- xfs_fileoff_t end_fsb, orig_end_fsb;
+ xfs_fileoff_t end_fsb;
int error = 0, eof = 0;
struct xfs_bmbt_irec got;
- struct xfs_bmbt_irec prev;
xfs_extnum_t idx;
+ xfs_fsblock_t prealloc_blocks = 0;
ASSERT(!XFS_IS_REALTIME_INODE(ip));
ASSERT(!xfs_get_extsz_hint(ip));
@@ -563,8 +564,7 @@ xfs_file_iomap_begin_delay(
goto out_unlock;
}
- xfs_bmap_search_extents(ip, offset_fsb, XFS_DATA_FORK, &eof, &idx,
- &got, &prev);
+ eof = !xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got);
if (!eof && got.br_startoff <= offset_fsb) {
if (xfs_is_reflink_inode(ip)) {
bool shared;
@@ -595,35 +595,32 @@ xfs_file_iomap_begin_delay(
* the lower level functions are updated.
*/
count = min_t(loff_t, count, 1024 * PAGE_SIZE);
- end_fsb = orig_end_fsb =
- min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb);
+ end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb);
if (eof) {
- xfs_fsblock_t prealloc_blocks;
-
- prealloc_blocks =
- xfs_iomap_prealloc_size(ip, offset, count, idx, &prev);
+ prealloc_blocks = xfs_iomap_prealloc_size(ip, offset, count, idx);
if (prealloc_blocks) {
xfs_extlen_t align;
xfs_off_t end_offset;
+ xfs_fileoff_t p_end_fsb;
end_offset = XFS_WRITEIO_ALIGN(mp, offset + count - 1);
- end_fsb = XFS_B_TO_FSBT(mp, end_offset) +
- prealloc_blocks;
+ p_end_fsb = XFS_B_TO_FSBT(mp, end_offset) +
+ prealloc_blocks;
align = xfs_eof_alignment(ip, 0);
if (align)
- end_fsb = roundup_64(end_fsb, align);
+ p_end_fsb = roundup_64(p_end_fsb, align);
- end_fsb = min(end_fsb, maxbytes_fsb);
- ASSERT(end_fsb > offset_fsb);
+ p_end_fsb = min(p_end_fsb, maxbytes_fsb);
+ ASSERT(p_end_fsb > offset_fsb);
+ prealloc_blocks = p_end_fsb - end_fsb;
}
}
retry:
error = xfs_bmapi_reserve_delalloc(ip, XFS_DATA_FORK, offset_fsb,
- end_fsb - offset_fsb, &got,
- &prev, &idx, eof);
+ end_fsb - offset_fsb, prealloc_blocks, &got, &idx, eof);
switch (error) {
case 0:
break;
@@ -631,8 +628,8 @@ retry:
case -EDQUOT:
/* retry without any preallocation */
trace_xfs_delalloc_enospc(ip, offset, count);
- if (end_fsb != orig_end_fsb) {
- end_fsb = orig_end_fsb;
+ if (prealloc_blocks) {
+ prealloc_blocks = 0;
goto retry;
}
/*FALLTHRU*/
@@ -640,13 +637,6 @@ retry:
goto out_unlock;
}
- /*
- * Tag the inode as speculatively preallocated so we can reclaim this
- * space on demand, if necessary.
- */
- if (end_fsb != orig_end_fsb)
- xfs_inode_set_eofblocks_tag(ip);
-
trace_xfs_iomap_alloc(ip, offset, count, 0, &got);
done:
if (isnullstartblock(got.br_startblock))
@@ -960,6 +950,19 @@ static inline bool imap_needs_alloc(struct inode *inode,
(IS_DAX(inode) && ISUNWRITTEN(imap));
}
+static inline bool need_excl_ilock(struct xfs_inode *ip, unsigned flags)
+{
+ /*
+ * COW writes will allocate delalloc space, so we need to make sure
+ * to take the lock exclusively here.
+ */
+ if (xfs_is_reflink_inode(ip) && (flags & (IOMAP_WRITE | IOMAP_ZERO)))
+ return true;
+ if ((flags & IOMAP_DIRECT) && (flags & IOMAP_WRITE))
+ return true;
+ return false;
+}
+
static int
xfs_file_iomap_begin(
struct inode *inode,
@@ -979,18 +982,14 @@ xfs_file_iomap_begin(
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
- if ((flags & IOMAP_WRITE) && !IS_DAX(inode) &&
- !xfs_get_extsz_hint(ip)) {
+ if (((flags & (IOMAP_WRITE | IOMAP_DIRECT)) == IOMAP_WRITE) &&
+ !IS_DAX(inode) && !xfs_get_extsz_hint(ip)) {
/* Reserve delalloc blocks for regular writeback. */
return xfs_file_iomap_begin_delay(inode, offset, length, flags,
iomap);
}
- /*
- * COW writes will allocate delalloc space, so we need to make sure
- * to take the lock exclusively here.
- */
- if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && xfs_is_reflink_inode(ip)) {
+ if (need_excl_ilock(ip, flags)) {
lockmode = XFS_ILOCK_EXCL;
xfs_ilock(ip, XFS_ILOCK_EXCL);
} else {
@@ -1003,17 +1002,41 @@ xfs_file_iomap_begin(
offset_fsb = XFS_B_TO_FSBT(mp, offset);
end_fsb = XFS_B_TO_FSB(mp, offset + length);
+ if (xfs_is_reflink_inode(ip) &&
+ (flags & IOMAP_WRITE) && (flags & IOMAP_DIRECT)) {
+ shared = xfs_reflink_find_cow_mapping(ip, offset, &imap);
+ if (shared) {
+ xfs_iunlock(ip, lockmode);
+ goto alloc_done;
+ }
+ ASSERT(!isnullstartblock(imap.br_startblock));
+ }
+
error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap,
&nimaps, 0);
if (error)
goto out_unlock;
- if (flags & IOMAP_REPORT) {
+ if ((flags & IOMAP_REPORT) ||
+ (xfs_is_reflink_inode(ip) &&
+ (flags & IOMAP_WRITE) && (flags & IOMAP_DIRECT))) {
/* Trim the mapping to the nearest shared extent boundary. */
error = xfs_reflink_trim_around_shared(ip, &imap, &shared,
&trimmed);
if (error)
goto out_unlock;
+
+ /*
+ * We're here because we're trying to do a directio write to a
+ * region that isn't aligned to a filesystem block. If the
+ * extent is shared, fall back to buffered mode to handle the
+ * RMW.
+ */
+ if (!(flags & IOMAP_REPORT) && shared) {
+ trace_xfs_reflink_bounce_dio_write(ip, &imap);
+ error = -EREMCHG;
+ goto out_unlock;
+ }
}
if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && xfs_is_reflink_inode(ip)) {
@@ -1048,6 +1071,7 @@ xfs_file_iomap_begin(
if (error)
return error;
+alloc_done:
iomap->flags = IOMAP_F_NEW;
trace_xfs_iomap_alloc(ip, offset, length, 0, &imap);
} else {
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 405a65cd9d6b..b930be0b1596 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -983,15 +983,13 @@ xfs_vn_setattr(
struct xfs_inode *ip = XFS_I(d_inode(dentry));
uint iolock = XFS_IOLOCK_EXCL;
- xfs_ilock(ip, iolock);
- error = xfs_break_layouts(d_inode(dentry), &iolock, true);
- if (!error) {
- xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
- iolock |= XFS_MMAPLOCK_EXCL;
+ error = xfs_break_layouts(d_inode(dentry), &iolock);
+ if (error)
+ return error;
- error = xfs_vn_setattr_size(dentry, iattr);
- }
- xfs_iunlock(ip, iolock);
+ xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
+ error = xfs_vn_setattr_size(dentry, iattr);
+ xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
} else {
error = xfs_vn_setattr_nonsize(dentry, iattr);
}
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 68640fb63a54..a415f822f2c1 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -78,6 +78,7 @@ typedef __u32 xfs_nlink_t;
#include <linux/freezer.h>
#include <linux/list_sort.h>
#include <linux/ratelimit.h>
+#include <linux/rhashtable.h>
#include <asm/page.h>
#include <asm/div64.h>
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 3b74fa011bb1..c39ac14ff540 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1668,7 +1668,7 @@ xlog_cksum(
__uint32_t crc;
/* first generate the crc for the record header ... */
- crc = xfs_start_cksum((char *)rhead,
+ crc = xfs_start_cksum_update((char *)rhead,
sizeof(struct xlog_rec_header),
offsetof(struct xlog_rec_header, h_crc));
@@ -1862,26 +1862,21 @@ xlog_sync(
bp->b_io_length = BTOBB(count);
bp->b_fspriv = iclog;
- bp->b_flags &= ~(XBF_FUA | XBF_FLUSH);
- bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE);
+ bp->b_flags &= ~XBF_FLUSH;
+ bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE | XBF_FUA);
- if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
- bp->b_flags |= XBF_FUA;
-
- /*
- * Flush the data device before flushing the log to make
- * sure all meta data written back from the AIL actually made
- * it to disk before stamping the new log tail LSN into the
- * log buffer. For an external log we need to issue the
- * flush explicitly, and unfortunately synchronously here;
- * for an internal log we can simply use the block layer
- * state machine for preflushes.
- */
- if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp)
- xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp);
- else
- bp->b_flags |= XBF_FLUSH;
- }
+ /*
+ * Flush the data device before flushing the log to make sure all meta
+ * data written back from the AIL actually made it to disk before
+ * stamping the new log tail LSN into the log buffer. For an external
+ * log we need to issue the flush explicitly, and unfortunately
+ * synchronously here; for an internal log we can simply use the block
+ * layer state machine for preflushes.
+ */
+ if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp)
+ xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp);
+ else
+ bp->b_flags |= XBF_FLUSH;
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
@@ -1906,10 +1901,8 @@ xlog_sync(
xfs_buf_associate_memory(bp,
(char *)&iclog->ic_header + count, split);
bp->b_fspriv = iclog;
- bp->b_flags &= ~(XBF_FUA | XBF_FLUSH);
- bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE);
- if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
- bp->b_flags |= XBF_FUA;
+ bp->b_flags &= ~XBF_FLUSH;
+ bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE | XBF_FUA);
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 9b3d7c76915d..4a98762ec8b4 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2025,7 +2025,7 @@ xlog_peek_buffer_cancelled(
struct xlog *log,
xfs_daddr_t blkno,
uint len,
- ushort flags)
+ unsigned short flags)
{
struct list_head *bucket;
struct xfs_buf_cancel *bcp;
@@ -2065,7 +2065,7 @@ xlog_check_buffer_cancelled(
struct xlog *log,
xfs_daddr_t blkno,
uint len,
- ushort flags)
+ unsigned short flags)
{
struct xfs_buf_cancel *bcp;
@@ -5113,19 +5113,21 @@ xlog_recover_process(
struct list_head *buffer_list)
{
int error;
+ __le32 old_crc = rhead->h_crc;
__le32 crc;
+
crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
/*
* Nothing else to do if this is a CRC verification pass. Just return
* if this a record with a non-zero crc. Unfortunately, mkfs always
- * sets h_crc to 0 so we must consider this valid even on v5 supers.
+ * sets old_crc to 0 so we must consider this valid even on v5 supers.
* Otherwise, return EFSBADCRC on failure so the callers up the stack
* know precisely what failed.
*/
if (pass == XLOG_RECOVER_CRCPASS) {
- if (rhead->h_crc && crc != rhead->h_crc)
+ if (old_crc && crc != old_crc)
return -EFSBADCRC;
return 0;
}
@@ -5136,11 +5138,11 @@ xlog_recover_process(
* zero CRC check prevents warnings from being emitted when upgrading
* the kernel from one that does not add CRCs by default.
*/
- if (crc != rhead->h_crc) {
- if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
+ if (crc != old_crc) {
+ if (old_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
xfs_alert(log->l_mp,
"log record CRC mismatch: found 0x%x, expected 0x%x.",
- le32_to_cpu(rhead->h_crc),
+ le32_to_cpu(old_crc),
le32_to_cpu(crc));
xfs_hex_dump(dp, 32);
}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b341f10cf481..9b9540db17a6 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -157,6 +157,7 @@ xfs_free_perag(
spin_unlock(&mp->m_perag_lock);
ASSERT(pag);
ASSERT(atomic_read(&pag->pag_ref) == 0);
+ xfs_buf_hash_destroy(pag);
call_rcu(&pag->rcu_head, __xfs_free_perag);
}
}
@@ -212,8 +213,8 @@ xfs_initialize_perag(
spin_lock_init(&pag->pag_ici_lock);
mutex_init(&pag->pag_ici_reclaim_lock);
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
- spin_lock_init(&pag->pag_buf_lock);
- pag->pag_buf_tree = RB_ROOT;
+ if (xfs_buf_hash_init(pag))
+ goto out_unwind;
if (radix_tree_preload(GFP_NOFS))
goto out_unwind;
@@ -239,9 +240,11 @@ xfs_initialize_perag(
return 0;
out_unwind:
+ xfs_buf_hash_destroy(pag);
kmem_free(pag);
for (; index > first_initialised; index--) {
pag = radix_tree_delete(&mp->m_perag_tree, index);
+ xfs_buf_hash_destroy(pag);
kmem_free(pag);
}
return error;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 819b80b15bfb..84f785218907 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -393,8 +393,8 @@ typedef struct xfs_perag {
unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */
/* buffer cache index */
- spinlock_t pag_buf_lock; /* lock for pag_buf_tree */
- struct rb_root pag_buf_tree; /* ordered tree of active buffers */
+ spinlock_t pag_buf_lock; /* lock for pag_buf_hash */
+ struct rhashtable pag_buf_hash;
/* for rcu-safe freeing */
struct rcu_head rcu_head;
@@ -424,6 +424,9 @@ xfs_perag_resv(
}
}
+int xfs_buf_hash_init(xfs_perag_t *pag);
+void xfs_buf_hash_destroy(xfs_perag_t *pag);
+
extern void xfs_uuid_table_free(void);
extern int xfs_log_sbcount(xfs_mount_t *);
extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index 93a7aafa56d6..2f2dc3c09ad0 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -32,8 +32,7 @@
int
xfs_break_layouts(
struct inode *inode,
- uint *iolock,
- bool with_imutex)
+ uint *iolock)
{
struct xfs_inode *ip = XFS_I(inode);
int error;
@@ -42,12 +41,8 @@ xfs_break_layouts(
while ((error = break_layout(inode, false) == -EWOULDBLOCK)) {
xfs_iunlock(ip, *iolock);
- if (with_imutex && (*iolock & XFS_IOLOCK_EXCL))
- inode_unlock(inode);
error = break_layout(inode, true);
*iolock = XFS_IOLOCK_EXCL;
- if (with_imutex)
- inode_lock(inode);
xfs_ilock(ip, *iolock);
}
diff --git a/fs/xfs/xfs_pnfs.h b/fs/xfs/xfs_pnfs.h
index e8339f74966b..b587cb99b2b7 100644
--- a/fs/xfs/xfs_pnfs.h
+++ b/fs/xfs/xfs_pnfs.h
@@ -8,10 +8,10 @@ int xfs_fs_map_blocks(struct inode *inode, loff_t offset, u64 length,
int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps,
struct iattr *iattr);
-int xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex);
+int xfs_break_layouts(struct inode *inode, uint *iolock);
#else
static inline int
-xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex)
+xfs_break_layouts(struct inode *inode, uint *iolock)
{
return 0;
}
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index a60d9e2739d1..45e50ea90769 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1135,7 +1135,7 @@ xfs_qm_get_rtblks(
return error;
}
rtblks = 0;
- nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+ nextents = xfs_iext_count(ifp);
for (idx = 0; idx < nextents; idx++)
rtblks += xfs_bmbt_get_blockcount(xfs_iext_get_ext(ifp, idx));
*O_rtblks = (xfs_qcnt_t)rtblks;
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index a279b4e7f5fe..88fd03c66e99 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -243,12 +243,11 @@ xfs_reflink_reserve_cow(
struct xfs_bmbt_irec *imap,
bool *shared)
{
- struct xfs_bmbt_irec got, prev;
- xfs_fileoff_t end_fsb, orig_end_fsb;
- int eof = 0, error = 0;
- bool trimmed;
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
+ struct xfs_bmbt_irec got;
+ int error = 0;
+ bool eof = false, trimmed;
xfs_extnum_t idx;
- xfs_extlen_t align;
/*
* Search the COW fork extent list first. This serves two purposes:
@@ -258,8 +257,9 @@ xfs_reflink_reserve_cow(
* extent list is generally faster than going out to the shared extent
* tree.
*/
- xfs_bmap_search_extents(ip, imap->br_startoff, XFS_COW_FORK, &eof, &idx,
- &got, &prev);
+
+ if (!xfs_iext_lookup_extent(ip, ifp, imap->br_startoff, &idx, &got))
+ eof = true;
if (!eof && got.br_startoff <= imap->br_startoff) {
trace_xfs_reflink_cow_found(ip, imap);
xfs_trim_extent(imap, got.br_startoff, got.br_blockcount);
@@ -285,33 +285,12 @@ xfs_reflink_reserve_cow(
if (error)
return error;
- end_fsb = orig_end_fsb = imap->br_startoff + imap->br_blockcount;
-
- align = xfs_eof_alignment(ip, xfs_get_cowextsz_hint(ip));
- if (align)
- end_fsb = roundup_64(end_fsb, align);
-
-retry:
error = xfs_bmapi_reserve_delalloc(ip, XFS_COW_FORK, imap->br_startoff,
- end_fsb - imap->br_startoff, &got, &prev, &idx, eof);
- switch (error) {
- case 0:
- break;
- case -ENOSPC:
- case -EDQUOT:
- /* retry without any preallocation */
+ imap->br_blockcount, 0, &got, &idx, eof);
+ if (error == -ENOSPC || error == -EDQUOT)
trace_xfs_reflink_cow_enospc(ip, imap);
- if (end_fsb != orig_end_fsb) {
- end_fsb = orig_end_fsb;
- goto retry;
- }
- /*FALLTHRU*/
- default:
+ if (error)
return error;
- }
-
- if (end_fsb != orig_end_fsb)
- xfs_inode_set_cowblocks_tag(ip);
trace_xfs_reflink_cow_alloc(ip, &got);
return 0;
@@ -418,87 +397,65 @@ xfs_reflink_allocate_cow_range(
}
/*
- * Find the CoW reservation (and whether or not it needs block allocation)
- * for a given byte offset of a file.
+ * Find the CoW reservation for a given byte offset of a file.
*/
bool
xfs_reflink_find_cow_mapping(
struct xfs_inode *ip,
xfs_off_t offset,
- struct xfs_bmbt_irec *imap,
- bool *need_alloc)
+ struct xfs_bmbt_irec *imap)
{
- struct xfs_bmbt_irec irec;
- struct xfs_ifork *ifp;
- struct xfs_bmbt_rec_host *gotp;
- xfs_fileoff_t bno;
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
+ xfs_fileoff_t offset_fsb;
+ struct xfs_bmbt_irec got;
xfs_extnum_t idx;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
ASSERT(xfs_is_reflink_inode(ip));
- /* Find the extent in the CoW fork. */
- ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
- bno = XFS_B_TO_FSBT(ip->i_mount, offset);
- gotp = xfs_iext_bno_to_ext(ifp, bno, &idx);
- if (!gotp)
+ offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
+ if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got))
return false;
-
- xfs_bmbt_get_all(gotp, &irec);
- if (bno >= irec.br_startoff + irec.br_blockcount ||
- bno < irec.br_startoff)
+ if (got.br_startoff > offset_fsb)
return false;
trace_xfs_reflink_find_cow_mapping(ip, offset, 1, XFS_IO_OVERWRITE,
- &irec);
-
- /* If it's still delalloc, we must allocate later. */
- *imap = irec;
- *need_alloc = !!(isnullstartblock(irec.br_startblock));
-
+ &got);
+ *imap = got;
return true;
}
/*
* Trim an extent to end at the next CoW reservation past offset_fsb.
*/
-int
+void
xfs_reflink_trim_irec_to_next_cow(
struct xfs_inode *ip,
xfs_fileoff_t offset_fsb,
struct xfs_bmbt_irec *imap)
{
- struct xfs_bmbt_irec irec;
- struct xfs_ifork *ifp;
- struct xfs_bmbt_rec_host *gotp;
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
+ struct xfs_bmbt_irec got;
xfs_extnum_t idx;
if (!xfs_is_reflink_inode(ip))
- return 0;
+ return;
/* Find the extent in the CoW fork. */
- ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
- gotp = xfs_iext_bno_to_ext(ifp, offset_fsb, &idx);
- if (!gotp)
- return 0;
- xfs_bmbt_get_all(gotp, &irec);
+ if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got))
+ return;
/* This is the extent before; try sliding up one. */
- if (irec.br_startoff < offset_fsb) {
- idx++;
- if (idx >= ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
- return 0;
- gotp = xfs_iext_get_ext(ifp, idx);
- xfs_bmbt_get_all(gotp, &irec);
+ if (got.br_startoff < offset_fsb) {
+ if (!xfs_iext_get_extent(ifp, idx + 1, &got))
+ return;
}
- if (irec.br_startoff >= imap->br_startoff + imap->br_blockcount)
- return 0;
+ if (got.br_startoff >= imap->br_startoff + imap->br_blockcount)
+ return;
- imap->br_blockcount = irec.br_startoff - imap->br_startoff;
+ imap->br_blockcount = got.br_startoff - imap->br_startoff;
trace_xfs_reflink_trim_irec(ip, imap);
-
- return 0;
}
/*
@@ -512,18 +469,15 @@ xfs_reflink_cancel_cow_blocks(
xfs_fileoff_t end_fsb)
{
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
- struct xfs_bmbt_irec got, prev, del;
+ struct xfs_bmbt_irec got, del;
xfs_extnum_t idx;
xfs_fsblock_t firstfsb;
struct xfs_defer_ops dfops;
- int error = 0, eof = 0;
+ int error = 0;
if (!xfs_is_reflink_inode(ip))
return 0;
-
- xfs_bmap_search_extents(ip, offset_fsb, XFS_COW_FORK, &eof, &idx,
- &got, &prev);
- if (eof)
+ if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &idx, &got))
return 0;
while (got.br_startoff < end_fsb) {
@@ -566,9 +520,8 @@ xfs_reflink_cancel_cow_blocks(
xfs_bmap_del_extent_cow(ip, &idx, &got, &del);
}
- if (++idx >= ifp->if_bytes / sizeof(struct xfs_bmbt_rec))
+ if (!xfs_iext_get_extent(ifp, ++idx, &got))
break;
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &got);
}
/* clear tag if cow fork is emptied */
@@ -638,13 +591,13 @@ xfs_reflink_end_cow(
xfs_off_t count)
{
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
- struct xfs_bmbt_irec got, prev, del;
+ struct xfs_bmbt_irec got, del;
struct xfs_trans *tp;
xfs_fileoff_t offset_fsb;
xfs_fileoff_t end_fsb;
xfs_fsblock_t firstfsb;
struct xfs_defer_ops dfops;
- int error, eof = 0;
+ int error;
unsigned int resblks;
xfs_filblks_t rlen;
xfs_extnum_t idx;
@@ -668,13 +621,11 @@ xfs_reflink_end_cow(
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0);
- xfs_bmap_search_extents(ip, end_fsb - 1, XFS_COW_FORK, &eof, &idx,
- &got, &prev);
-
/* If there is a hole at end_fsb - 1 go to the previous extent */
- if (eof || got.br_startoff > end_fsb) {
+ if (!xfs_iext_lookup_extent(ip, ifp, end_fsb - 1, &idx, &got) ||
+ got.br_startoff > end_fsb) {
ASSERT(idx > 0);
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, --idx), &got);
+ xfs_iext_get_extent(ifp, --idx, &got);
}
/* Walk backwards until we're out of the I/O range... */
@@ -722,11 +673,9 @@ xfs_reflink_end_cow(
error = xfs_defer_finish(&tp, &dfops, ip);
if (error)
goto out_defer;
-
next_extent:
- if (idx < 0)
+ if (!xfs_iext_get_extent(ifp, idx, &got))
break;
- xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &got);
}
error = xfs_trans_commit(tp);
@@ -1302,13 +1251,11 @@ xfs_reflink_remap_range(
return -EIO;
/* Lock both files against IO */
- if (same_inode) {
- xfs_ilock(src, XFS_IOLOCK_EXCL);
+ lock_two_nondirectories(inode_in, inode_out);
+ if (same_inode)
xfs_ilock(src, XFS_MMAPLOCK_EXCL);
- } else {
- xfs_lock_two_inodes(src, dest, XFS_IOLOCK_EXCL);
+ else
xfs_lock_two_inodes(src, dest, XFS_MMAPLOCK_EXCL);
- }
/* Don't touch certain kinds of inodes */
ret = -EPERM;
@@ -1345,8 +1292,14 @@ xfs_reflink_remap_range(
goto out_unlock;
}
- if (len == 0)
+ /* Zero length dedupe exits immediately; reflink goes to EOF. */
+ if (len == 0) {
+ if (is_dedupe) {
+ ret = 0;
+ goto out_unlock;
+ }
len = isize - pos_in;
+ }
/* Ensure offsets don't wrap and the input is inside i_size */
if (pos_in + len < pos_in || pos_out + len < pos_out ||
@@ -1447,11 +1400,9 @@ xfs_reflink_remap_range(
out_unlock:
xfs_iunlock(src, XFS_MMAPLOCK_EXCL);
- xfs_iunlock(src, XFS_IOLOCK_EXCL);
- if (src->i_ino != dest->i_ino) {
+ if (!same_inode)
xfs_iunlock(dest, XFS_MMAPLOCK_EXCL);
- xfs_iunlock(dest, XFS_IOLOCK_EXCL);
- }
+ unlock_two_nondirectories(inode_in, inode_out);
if (ret)
trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
return ret;
@@ -1697,37 +1648,3 @@ out:
trace_xfs_reflink_unshare_error(ip, error, _RET_IP_);
return error;
}
-
-/*
- * Does this inode have any real CoW reservations?
- */
-bool
-xfs_reflink_has_real_cow_blocks(
- struct xfs_inode *ip)
-{
- struct xfs_bmbt_irec irec;
- struct xfs_ifork *ifp;
- struct xfs_bmbt_rec_host *gotp;
- xfs_extnum_t idx;
-
- if (!xfs_is_reflink_inode(ip))
- return false;
-
- /* Go find the old extent in the CoW fork. */
- ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
- gotp = xfs_iext_bno_to_ext(ifp, 0, &idx);
- while (gotp) {
- xfs_bmbt_get_all(gotp, &irec);
-
- if (!isnullstartblock(irec.br_startblock))
- return true;
-
- /* Roll on... */
- idx++;
- if (idx >= ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
- break;
- gotp = xfs_iext_get_ext(ifp, idx);
- }
-
- return false;
-}
diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h
index fad11607c9ad..aa6a4d64bd35 100644
--- a/fs/xfs/xfs_reflink.h
+++ b/fs/xfs/xfs_reflink.h
@@ -31,8 +31,8 @@ extern int xfs_reflink_reserve_cow(struct xfs_inode *ip,
extern int xfs_reflink_allocate_cow_range(struct xfs_inode *ip,
xfs_off_t offset, xfs_off_t count);
extern bool xfs_reflink_find_cow_mapping(struct xfs_inode *ip, xfs_off_t offset,
- struct xfs_bmbt_irec *imap, bool *need_alloc);
-extern int xfs_reflink_trim_irec_to_next_cow(struct xfs_inode *ip,
+ struct xfs_bmbt_irec *imap);
+extern void xfs_reflink_trim_irec_to_next_cow(struct xfs_inode *ip,
xfs_fileoff_t offset_fsb, struct xfs_bmbt_irec *imap);
extern int xfs_reflink_cancel_cow_blocks(struct xfs_inode *ip,
@@ -50,6 +50,4 @@ extern int xfs_reflink_clear_inode_flag(struct xfs_inode *ip,
extern int xfs_reflink_unshare(struct xfs_inode *ip, xfs_off_t offset,
xfs_off_t len);
-extern bool xfs_reflink_has_real_cow_blocks(struct xfs_inode *ip);
-
#endif /* __XFS_REFLINK_H */
diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c
index 12d48cd8f8a4..f11282c96887 100644
--- a/fs/xfs/xfs_stats.c
+++ b/fs/xfs/xfs_stats.c
@@ -80,9 +80,9 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
}
/* extra precision counters */
for_each_possible_cpu(i) {
- xs_xstrat_bytes += per_cpu_ptr(stats, i)->xs_xstrat_bytes;
- xs_write_bytes += per_cpu_ptr(stats, i)->xs_write_bytes;
- xs_read_bytes += per_cpu_ptr(stats, i)->xs_read_bytes;
+ xs_xstrat_bytes += per_cpu_ptr(stats, i)->s.xs_xstrat_bytes;
+ xs_write_bytes += per_cpu_ptr(stats, i)->s.xs_write_bytes;
+ xs_read_bytes += per_cpu_ptr(stats, i)->s.xs_read_bytes;
}
len += snprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n",
@@ -106,9 +106,9 @@ void xfs_stats_clearall(struct xfsstats __percpu *stats)
for_each_possible_cpu(c) {
preempt_disable();
/* save vn_active, it's a universal truth! */
- vn_active = per_cpu_ptr(stats, c)->vn_active;
+ vn_active = per_cpu_ptr(stats, c)->s.vn_active;
memset(per_cpu_ptr(stats, c), 0, sizeof(*stats));
- per_cpu_ptr(stats, c)->vn_active = vn_active;
+ per_cpu_ptr(stats, c)->s.vn_active = vn_active;
preempt_enable();
}
}
diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h
index 79ad2e69fc33..375840f5a99a 100644
--- a/fs/xfs/xfs_stats.h
+++ b/fs/xfs/xfs_stats.h
@@ -22,9 +22,37 @@
#include <linux/percpu.h>
/*
+ * The btree stats arrays have fixed offsets for the different stats. We
+ * store the base index in the btree cursor via XFS_STATS_CALC_INDEX() and
+ * that allows us to use fixed offsets into the stats array for each btree
+ * stat. These index offsets are defined in the order they will be emitted
+ * in the stats files, so it is possible to add new btree stat types by
+ * appending to the enum list below.
+ */
+enum {
+ __XBTS_lookup = 0,
+ __XBTS_compare = 1,
+ __XBTS_insrec = 2,
+ __XBTS_delrec = 3,
+ __XBTS_newroot = 4,
+ __XBTS_killroot = 5,
+ __XBTS_increment = 6,
+ __XBTS_decrement = 7,
+ __XBTS_lshift = 8,
+ __XBTS_rshift = 9,
+ __XBTS_split = 10,
+ __XBTS_join = 11,
+ __XBTS_alloc = 12,
+ __XBTS_free = 13,
+ __XBTS_moves = 14,
+
+ __XBTS_MAX = 15,
+};
+
+/*
* XFS global statistics
*/
-struct xfsstats {
+struct __xfsstats {
# define XFSSTAT_END_EXTENT_ALLOC 4
__uint32_t xs_allocx;
__uint32_t xs_allocb;
@@ -117,118 +145,20 @@ struct xfsstats {
__uint32_t xb_page_found;
__uint32_t xb_get_read;
/* Version 2 btree counters */
-#define XFSSTAT_END_ABTB_V2 (XFSSTAT_END_BUF+15)
- __uint32_t xs_abtb_2_lookup;
- __uint32_t xs_abtb_2_compare;
- __uint32_t xs_abtb_2_insrec;
- __uint32_t xs_abtb_2_delrec;
- __uint32_t xs_abtb_2_newroot;
- __uint32_t xs_abtb_2_killroot;
- __uint32_t xs_abtb_2_increment;
- __uint32_t xs_abtb_2_decrement;
- __uint32_t xs_abtb_2_lshift;
- __uint32_t xs_abtb_2_rshift;
- __uint32_t xs_abtb_2_split;
- __uint32_t xs_abtb_2_join;
- __uint32_t xs_abtb_2_alloc;
- __uint32_t xs_abtb_2_free;
- __uint32_t xs_abtb_2_moves;
-#define XFSSTAT_END_ABTC_V2 (XFSSTAT_END_ABTB_V2+15)
- __uint32_t xs_abtc_2_lookup;
- __uint32_t xs_abtc_2_compare;
- __uint32_t xs_abtc_2_insrec;
- __uint32_t xs_abtc_2_delrec;
- __uint32_t xs_abtc_2_newroot;
- __uint32_t xs_abtc_2_killroot;
- __uint32_t xs_abtc_2_increment;
- __uint32_t xs_abtc_2_decrement;
- __uint32_t xs_abtc_2_lshift;
- __uint32_t xs_abtc_2_rshift;
- __uint32_t xs_abtc_2_split;
- __uint32_t xs_abtc_2_join;
- __uint32_t xs_abtc_2_alloc;
- __uint32_t xs_abtc_2_free;
- __uint32_t xs_abtc_2_moves;
-#define XFSSTAT_END_BMBT_V2 (XFSSTAT_END_ABTC_V2+15)
- __uint32_t xs_bmbt_2_lookup;
- __uint32_t xs_bmbt_2_compare;
- __uint32_t xs_bmbt_2_insrec;
- __uint32_t xs_bmbt_2_delrec;
- __uint32_t xs_bmbt_2_newroot;
- __uint32_t xs_bmbt_2_killroot;
- __uint32_t xs_bmbt_2_increment;
- __uint32_t xs_bmbt_2_decrement;
- __uint32_t xs_bmbt_2_lshift;
- __uint32_t xs_bmbt_2_rshift;
- __uint32_t xs_bmbt_2_split;
- __uint32_t xs_bmbt_2_join;
- __uint32_t xs_bmbt_2_alloc;
- __uint32_t xs_bmbt_2_free;
- __uint32_t xs_bmbt_2_moves;
-#define XFSSTAT_END_IBT_V2 (XFSSTAT_END_BMBT_V2+15)
- __uint32_t xs_ibt_2_lookup;
- __uint32_t xs_ibt_2_compare;
- __uint32_t xs_ibt_2_insrec;
- __uint32_t xs_ibt_2_delrec;
- __uint32_t xs_ibt_2_newroot;
- __uint32_t xs_ibt_2_killroot;
- __uint32_t xs_ibt_2_increment;
- __uint32_t xs_ibt_2_decrement;
- __uint32_t xs_ibt_2_lshift;
- __uint32_t xs_ibt_2_rshift;
- __uint32_t xs_ibt_2_split;
- __uint32_t xs_ibt_2_join;
- __uint32_t xs_ibt_2_alloc;
- __uint32_t xs_ibt_2_free;
- __uint32_t xs_ibt_2_moves;
-#define XFSSTAT_END_FIBT_V2 (XFSSTAT_END_IBT_V2+15)
- __uint32_t xs_fibt_2_lookup;
- __uint32_t xs_fibt_2_compare;
- __uint32_t xs_fibt_2_insrec;
- __uint32_t xs_fibt_2_delrec;
- __uint32_t xs_fibt_2_newroot;
- __uint32_t xs_fibt_2_killroot;
- __uint32_t xs_fibt_2_increment;
- __uint32_t xs_fibt_2_decrement;
- __uint32_t xs_fibt_2_lshift;
- __uint32_t xs_fibt_2_rshift;
- __uint32_t xs_fibt_2_split;
- __uint32_t xs_fibt_2_join;
- __uint32_t xs_fibt_2_alloc;
- __uint32_t xs_fibt_2_free;
- __uint32_t xs_fibt_2_moves;
-#define XFSSTAT_END_RMAP_V2 (XFSSTAT_END_FIBT_V2+15)
- __uint32_t xs_rmap_2_lookup;
- __uint32_t xs_rmap_2_compare;
- __uint32_t xs_rmap_2_insrec;
- __uint32_t xs_rmap_2_delrec;
- __uint32_t xs_rmap_2_newroot;
- __uint32_t xs_rmap_2_killroot;
- __uint32_t xs_rmap_2_increment;
- __uint32_t xs_rmap_2_decrement;
- __uint32_t xs_rmap_2_lshift;
- __uint32_t xs_rmap_2_rshift;
- __uint32_t xs_rmap_2_split;
- __uint32_t xs_rmap_2_join;
- __uint32_t xs_rmap_2_alloc;
- __uint32_t xs_rmap_2_free;
- __uint32_t xs_rmap_2_moves;
-#define XFSSTAT_END_REFCOUNT (XFSSTAT_END_RMAP_V2 + 15)
- __uint32_t xs_refcbt_2_lookup;
- __uint32_t xs_refcbt_2_compare;
- __uint32_t xs_refcbt_2_insrec;
- __uint32_t xs_refcbt_2_delrec;
- __uint32_t xs_refcbt_2_newroot;
- __uint32_t xs_refcbt_2_killroot;
- __uint32_t xs_refcbt_2_increment;
- __uint32_t xs_refcbt_2_decrement;
- __uint32_t xs_refcbt_2_lshift;
- __uint32_t xs_refcbt_2_rshift;
- __uint32_t xs_refcbt_2_split;
- __uint32_t xs_refcbt_2_join;
- __uint32_t xs_refcbt_2_alloc;
- __uint32_t xs_refcbt_2_free;
- __uint32_t xs_refcbt_2_moves;
+#define XFSSTAT_END_ABTB_V2 (XFSSTAT_END_BUF + __XBTS_MAX)
+ __uint32_t xs_abtb_2[__XBTS_MAX];
+#define XFSSTAT_END_ABTC_V2 (XFSSTAT_END_ABTB_V2 + __XBTS_MAX)
+ __uint32_t xs_abtc_2[__XBTS_MAX];
+#define XFSSTAT_END_BMBT_V2 (XFSSTAT_END_ABTC_V2 + __XBTS_MAX)
+ __uint32_t xs_bmbt_2[__XBTS_MAX];
+#define XFSSTAT_END_IBT_V2 (XFSSTAT_END_BMBT_V2 + __XBTS_MAX)
+ __uint32_t xs_ibt_2[__XBTS_MAX];
+#define XFSSTAT_END_FIBT_V2 (XFSSTAT_END_IBT_V2 + __XBTS_MAX)
+ __uint32_t xs_fibt_2[__XBTS_MAX];
+#define XFSSTAT_END_RMAP_V2 (XFSSTAT_END_FIBT_V2 + __XBTS_MAX)
+ __uint32_t xs_rmap_2[__XBTS_MAX];
+#define XFSSTAT_END_REFCOUNT (XFSSTAT_END_RMAP_V2 + __XBTS_MAX)
+ __uint32_t xs_refcbt_2[__XBTS_MAX];
#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_REFCOUNT + 6)
__uint32_t xs_qm_dqreclaims;
__uint32_t xs_qm_dqreclaim_misses;
@@ -245,26 +175,58 @@ struct xfsstats {
__uint64_t xs_read_bytes;
};
+struct xfsstats {
+ union {
+ struct __xfsstats s;
+ uint32_t a[XFSSTAT_END_XQMSTAT];
+ };
+};
+
+/*
+ * simple wrapper for getting the array index of s struct member offset
+ */
+#define XFS_STATS_CALC_INDEX(member) \
+ (offsetof(struct __xfsstats, member) / (int)sizeof(__uint32_t))
+
+
int xfs_stats_format(struct xfsstats __percpu *stats, char *buf);
void xfs_stats_clearall(struct xfsstats __percpu *stats);
extern struct xstats xfsstats;
#define XFS_STATS_INC(mp, v) \
do { \
- per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++; \
- per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++; \
+ per_cpu_ptr(xfsstats.xs_stats, current_cpu())->s.v++; \
+ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->s.v++; \
} while (0)
#define XFS_STATS_DEC(mp, v) \
do { \
- per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--; \
- per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--; \
+ per_cpu_ptr(xfsstats.xs_stats, current_cpu())->s.v--; \
+ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->s.v--; \
} while (0)
#define XFS_STATS_ADD(mp, v, inc) \
do { \
- per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc); \
- per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \
+ per_cpu_ptr(xfsstats.xs_stats, current_cpu())->s.v += (inc); \
+ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->s.v += (inc); \
+} while (0)
+
+#define XFS_STATS_INC_OFF(mp, off) \
+do { \
+ per_cpu_ptr(xfsstats.xs_stats, current_cpu())->a[off]++; \
+ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->a[off]++; \
+} while (0)
+
+#define XFS_STATS_DEC_OFF(mp, off) \
+do { \
+ per_cpu_ptr(xfsstats.xs_stats, current_cpu())->a[off]; \
+ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->a[off]; \
+} while (0)
+
+#define XFS_STATS_ADD_OFF(mp, off, inc) \
+do { \
+ per_cpu_ptr(xfsstats.xs_stats, current_cpu())->a[off] += (inc); \
+ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->a[off] += (inc); \
} while (0)
#if defined(CONFIG_PROC_FS)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index ade4691e3f74..eecbaac08eba 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -104,9 +104,6 @@ static const match_table_t tokens = {
{Opt_sysvgroups,"sysvgroups"}, /* group-ID from current process */
{Opt_allocsize, "allocsize=%s"},/* preferred allocation size */
{Opt_norecovery,"norecovery"}, /* don't run XFS recovery */
- {Opt_barrier, "barrier"}, /* use writer barriers for log write and
- * unwritten extent conversion */
- {Opt_nobarrier, "nobarrier"}, /* .. disable */
{Opt_inode64, "inode64"}, /* inodes can be allocated anywhere */
{Opt_inode32, "inode32"}, /* inode allocation limited to
* XFS_MAXINUMBER_32 */
@@ -134,6 +131,12 @@ static const match_table_t tokens = {
{Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */
{Opt_dax, "dax"}, /* Enable direct access to bdev pages */
+
+ /* Deprecated mount options scheduled for removal */
+ {Opt_barrier, "barrier"}, /* use writer barriers for log write and
+ * unwritten extent conversion */
+ {Opt_nobarrier, "nobarrier"}, /* .. disable */
+
{Opt_err, NULL},
};
@@ -301,12 +304,6 @@ xfs_parseargs(
case Opt_nouuid:
mp->m_flags |= XFS_MOUNT_NOUUID;
break;
- case Opt_barrier:
- mp->m_flags |= XFS_MOUNT_BARRIER;
- break;
- case Opt_nobarrier:
- mp->m_flags &= ~XFS_MOUNT_BARRIER;
- break;
case Opt_ikeep:
mp->m_flags |= XFS_MOUNT_IKEEP;
break;
@@ -374,6 +371,14 @@ xfs_parseargs(
mp->m_flags |= XFS_MOUNT_DAX;
break;
#endif
+ case Opt_barrier:
+ xfs_warn(mp, "%s option is deprecated, ignoring.", p);
+ mp->m_flags |= XFS_MOUNT_BARRIER;
+ break;
+ case Opt_nobarrier:
+ xfs_warn(mp, "%s option is deprecated, ignoring.", p);
+ mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ break;
default:
xfs_warn(mp, "unknown mount option [%s].", p);
return -EINVAL;
@@ -943,7 +948,7 @@ xfs_fs_destroy_inode(
trace_xfs_destroy_inode(ip);
- ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
+ ASSERT(!rwsem_is_locked(&inode->i_rwsem));
XFS_STATS_INC(ip->i_mount, vn_rele);
XFS_STATS_INC(ip->i_mount, vn_remove);
@@ -1238,9 +1243,11 @@ xfs_fs_remount(
token = match_token(p, tokens, args);
switch (token) {
case Opt_barrier:
+ xfs_warn(mp, "%s option is deprecated, ignoring.", p);
mp->m_flags |= XFS_MOUNT_BARRIER;
break;
case Opt_nobarrier:
+ xfs_warn(mp, "%s option is deprecated, ignoring.", p);
mp->m_flags &= ~XFS_MOUNT_BARRIER;
break;
case Opt_inode64:
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 58142aeeeea6..f2cb45ed1d54 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -238,8 +238,7 @@ xfs_symlink(
if (error)
goto out_release_inode;
- xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
- XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
+ xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
unlock_dp_on_error = true;
/*
@@ -287,7 +286,7 @@ xfs_symlink(
* the transaction cancel unlocking dp so don't do it explicitly in the
* error path.
*/
- xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
unlock_dp_on_error = false;
/*
@@ -412,7 +411,7 @@ out_release_inode:
xfs_qm_dqrele(pdqp);
if (unlock_dp_on_error)
- xfs_iunlock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+ xfs_iunlock(dp, XFS_ILOCK_EXCL);
return error;
}
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 0907752be62d..69c5bcd9a51b 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -355,7 +355,6 @@ DEFINE_BUF_EVENT(xfs_buf_rele);
DEFINE_BUF_EVENT(xfs_buf_iodone);
DEFINE_BUF_EVENT(xfs_buf_submit);
DEFINE_BUF_EVENT(xfs_buf_submit_wait);
-DEFINE_BUF_EVENT(xfs_buf_bawrite);
DEFINE_BUF_EVENT(xfs_buf_lock);
DEFINE_BUF_EVENT(xfs_buf_lock_done);
DEFINE_BUF_EVENT(xfs_buf_trylock_fail);
@@ -367,19 +366,15 @@ DEFINE_BUF_EVENT(xfs_buf_delwri_queue);
DEFINE_BUF_EVENT(xfs_buf_delwri_queued);
DEFINE_BUF_EVENT(xfs_buf_delwri_split);
DEFINE_BUF_EVENT(xfs_buf_get_uncached);
-DEFINE_BUF_EVENT(xfs_bdstrat_shut);
DEFINE_BUF_EVENT(xfs_buf_item_relse);
DEFINE_BUF_EVENT(xfs_buf_item_iodone_async);
DEFINE_BUF_EVENT(xfs_buf_error_relse);
DEFINE_BUF_EVENT(xfs_buf_wait_buftarg);
-DEFINE_BUF_EVENT(xfs_trans_read_buf_io);
DEFINE_BUF_EVENT(xfs_trans_read_buf_shut);
/* not really buffer traces, but the buf provides useful information */
DEFINE_BUF_EVENT(xfs_btree_corrupt);
-DEFINE_BUF_EVENT(xfs_da_btree_corrupt);
DEFINE_BUF_EVENT(xfs_reset_dqcounts);
-DEFINE_BUF_EVENT(xfs_inode_item_push);
/* pass flags explicitly */
DECLARE_EVENT_CLASS(xfs_buf_flags_class,
@@ -541,7 +536,6 @@ DEFINE_BUF_ITEM_EVENT(xfs_trans_bjoin);
DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold);
DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release);
DEFINE_BUF_ITEM_EVENT(xfs_trans_binval);
-DEFINE_BUF_ITEM_EVENT(xfs_trans_buf_ordered);
DECLARE_EVENT_CLASS(xfs_filestream_class,
TP_PROTO(struct xfs_inode *ip, xfs_agnumber_t agno),
@@ -680,7 +674,6 @@ DEFINE_INODE_EVENT(xfs_ioctl_setattr);
DEFINE_INODE_EVENT(xfs_dir_fsync);
DEFINE_INODE_EVENT(xfs_file_fsync);
DEFINE_INODE_EVENT(xfs_destroy_inode);
-DEFINE_INODE_EVENT(xfs_evict_inode);
DEFINE_INODE_EVENT(xfs_update_time);
DEFINE_INODE_EVENT(xfs_dquot_dqalloc);
@@ -798,7 +791,6 @@ TRACE_EVENT(xfs_irec_merge_post,
DEFINE_EVENT(xfs_iref_class, name, \
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \
TP_ARGS(ip, caller_ip))
-DEFINE_IREF_EVENT(xfs_ihold);
DEFINE_IREF_EVENT(xfs_irele);
DEFINE_IREF_EVENT(xfs_inode_pin);
DEFINE_IREF_EVENT(xfs_inode_unpin);
@@ -939,7 +931,6 @@ DEFINE_DQUOT_EVENT(xfs_dqget_miss);
DEFINE_DQUOT_EVENT(xfs_dqget_freeing);
DEFINE_DQUOT_EVENT(xfs_dqget_dup);
DEFINE_DQUOT_EVENT(xfs_dqput);
-DEFINE_DQUOT_EVENT(xfs_dqput_wait);
DEFINE_DQUOT_EVENT(xfs_dqput_free);
DEFINE_DQUOT_EVENT(xfs_dqrele);
DEFINE_DQUOT_EVENT(xfs_dqflush);
@@ -1815,7 +1806,6 @@ DEFINE_ATTR_EVENT(xfs_attr_sf_addname);
DEFINE_ATTR_EVENT(xfs_attr_sf_create);
DEFINE_ATTR_EVENT(xfs_attr_sf_lookup);
DEFINE_ATTR_EVENT(xfs_attr_sf_remove);
-DEFINE_ATTR_EVENT(xfs_attr_sf_removename);
DEFINE_ATTR_EVENT(xfs_attr_sf_to_leaf);
DEFINE_ATTR_EVENT(xfs_attr_leaf_add);
@@ -1844,7 +1834,6 @@ DEFINE_ATTR_EVENT(xfs_attr_leaf_toosmall);
DEFINE_ATTR_EVENT(xfs_attr_node_addname);
DEFINE_ATTR_EVENT(xfs_attr_node_get);
-DEFINE_ATTR_EVENT(xfs_attr_node_lookup);
DEFINE_ATTR_EVENT(xfs_attr_node_replace);
DEFINE_ATTR_EVENT(xfs_attr_node_removename);
@@ -2440,11 +2429,9 @@ DEFINE_DEFER_EVENT(xfs_defer_finish_done);
DEFINE_DEFER_ERROR_EVENT(xfs_defer_trans_roll_error);
DEFINE_DEFER_ERROR_EVENT(xfs_defer_finish_error);
-DEFINE_DEFER_ERROR_EVENT(xfs_defer_op_finish_error);
DEFINE_DEFER_PENDING_EVENT(xfs_defer_intake_work);
DEFINE_DEFER_PENDING_EVENT(xfs_defer_intake_cancel);
-DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_commit);
DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_cancel);
DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_finish);
DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_abort);
@@ -3092,87 +3079,6 @@ DEFINE_EVENT(xfs_double_io_class, name, \
struct xfs_inode *dest, xfs_off_t doffset), \
TP_ARGS(src, soffset, len, dest, doffset))
-/* two-file vfs io tracepoint class */
-DECLARE_EVENT_CLASS(xfs_double_vfs_io_class,
- TP_PROTO(struct inode *src, u64 soffset, u64 len,
- struct inode *dest, u64 doffset),
- TP_ARGS(src, soffset, len, dest, doffset),
- TP_STRUCT__entry(
- __field(dev_t, dev)
- __field(unsigned long, src_ino)
- __field(loff_t, src_isize)
- __field(loff_t, src_offset)
- __field(size_t, len)
- __field(unsigned long, dest_ino)
- __field(loff_t, dest_isize)
- __field(loff_t, dest_offset)
- ),
- TP_fast_assign(
- __entry->dev = src->i_sb->s_dev;
- __entry->src_ino = src->i_ino;
- __entry->src_isize = i_size_read(src);
- __entry->src_offset = soffset;
- __entry->len = len;
- __entry->dest_ino = dest->i_ino;
- __entry->dest_isize = i_size_read(dest);
- __entry->dest_offset = doffset;
- ),
- TP_printk("dev %d:%d count %zd "
- "ino 0x%lx isize 0x%llx offset 0x%llx -> "
- "ino 0x%lx isize 0x%llx offset 0x%llx",
- MAJOR(__entry->dev), MINOR(__entry->dev),
- __entry->len,
- __entry->src_ino,
- __entry->src_isize,
- __entry->src_offset,
- __entry->dest_ino,
- __entry->dest_isize,
- __entry->dest_offset)
-)
-
-#define DEFINE_DOUBLE_VFS_IO_EVENT(name) \
-DEFINE_EVENT(xfs_double_vfs_io_class, name, \
- TP_PROTO(struct inode *src, u64 soffset, u64 len, \
- struct inode *dest, u64 doffset), \
- TP_ARGS(src, soffset, len, dest, doffset))
-
-/* CoW write tracepoint */
-DECLARE_EVENT_CLASS(xfs_copy_on_write_class,
- TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t lblk, xfs_fsblock_t pblk,
- xfs_extlen_t len, xfs_fsblock_t new_pblk),
- TP_ARGS(ip, lblk, pblk, len, new_pblk),
- TP_STRUCT__entry(
- __field(dev_t, dev)
- __field(xfs_ino_t, ino)
- __field(xfs_fileoff_t, lblk)
- __field(xfs_fsblock_t, pblk)
- __field(xfs_extlen_t, len)
- __field(xfs_fsblock_t, new_pblk)
- ),
- TP_fast_assign(
- __entry->dev = VFS_I(ip)->i_sb->s_dev;
- __entry->ino = ip->i_ino;
- __entry->lblk = lblk;
- __entry->pblk = pblk;
- __entry->len = len;
- __entry->new_pblk = new_pblk;
- ),
- TP_printk("dev %d:%d ino 0x%llx lblk 0x%llx pblk 0x%llx "
- "len 0x%x new_pblk %llu",
- MAJOR(__entry->dev), MINOR(__entry->dev),
- __entry->ino,
- __entry->lblk,
- __entry->pblk,
- __entry->len,
- __entry->new_pblk)
-)
-
-#define DEFINE_COW_EVENT(name) \
-DEFINE_EVENT(xfs_copy_on_write_class, name, \
- TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t lblk, xfs_fsblock_t pblk, \
- xfs_extlen_t len, xfs_fsblock_t new_pblk), \
- TP_ARGS(ip, lblk, pblk, len, new_pblk))
-
/* inode/irec events */
DECLARE_EVENT_CLASS(xfs_inode_irec_class,
TP_PROTO(struct xfs_inode *ip, struct xfs_bmbt_irec *irec),
@@ -3292,8 +3198,6 @@ DEFINE_DOUBLE_IO_EVENT(xfs_reflink_remap_range);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_remap_range_error);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_set_inode_flag_error);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_update_inode_size_error);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_reflink_main_loop_error);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_read_iomap_error);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_remap_blocks_error);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_remap_extent_error);
@@ -3302,9 +3206,6 @@ DEFINE_DOUBLE_IO_EVENT(xfs_reflink_compare_extents);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_compare_extents_error);
/* ioctl tracepoints */
-DEFINE_DOUBLE_VFS_IO_EVENT(xfs_ioctl_reflink);
-DEFINE_DOUBLE_VFS_IO_EVENT(xfs_ioctl_clone_range);
-DEFINE_DOUBLE_VFS_IO_EVENT(xfs_ioctl_file_extent_same);
TRACE_EVENT(xfs_ioctl_clone,
TP_PROTO(struct inode *src, struct inode *dest),
TP_ARGS(src, dest),
@@ -3334,11 +3235,7 @@ TRACE_EVENT(xfs_ioctl_clone,
/* unshare tracepoints */
DEFINE_SIMPLE_IO_EVENT(xfs_reflink_unshare);
-DEFINE_SIMPLE_IO_EVENT(xfs_reflink_cow_eof_block);
-DEFINE_PAGE_EVENT(xfs_reflink_unshare_page);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_unshare_error);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_cow_eof_block_error);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_dirty_page_error);
/* copy on write */
DEFINE_INODE_IREC_EVENT(xfs_reflink_trim_around_shared);
@@ -3361,14 +3258,8 @@ DEFINE_INODE_ERROR_EVENT(xfs_reflink_allocate_cow_range_error);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_cancel_cow_range_error);
DEFINE_INODE_ERROR_EVENT(xfs_reflink_end_cow_error);
-DEFINE_COW_EVENT(xfs_reflink_fork_buf);
-DEFINE_COW_EVENT(xfs_reflink_finish_fork_buf);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_fork_buf_error);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_finish_fork_buf_error);
-DEFINE_INODE_EVENT(xfs_reflink_cancel_pending_cow);
DEFINE_INODE_IREC_EVENT(xfs_reflink_cancel_cow);
-DEFINE_INODE_ERROR_EVENT(xfs_reflink_cancel_pending_cow_error);
/* rmap swapext tracepoints */
DEFINE_INODE_IREC_EVENT(xfs_swap_extent_rmap_remap);
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 62900938f26d..0594db435972 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -130,7 +130,7 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
NULL
};
-static int
+static void
__xfs_xattr_put_listent(
struct xfs_attr_list_context *context,
char *prefix,
@@ -148,7 +148,7 @@ __xfs_xattr_put_listent(
if (arraytop > context->firstu) {
context->count = -1; /* insufficient space */
context->seen_enough = 1;
- return 0;
+ return;
}
offset = (char *)context->alist + context->count;
strncpy(offset, prefix, prefix_len);
@@ -159,10 +159,10 @@ __xfs_xattr_put_listent(
compute_size:
context->count += prefix_len + namelen + 1;
- return 0;
+ return;
}
-static int
+static void
xfs_xattr_put_listent(
struct xfs_attr_list_context *context,
int flags,
@@ -180,23 +180,19 @@ xfs_xattr_put_listent(
if (namelen == SGI_ACL_FILE_SIZE &&
strncmp(name, SGI_ACL_FILE,
SGI_ACL_FILE_SIZE) == 0) {
- int ret = __xfs_xattr_put_listent(
+ __xfs_xattr_put_listent(
context, XATTR_SYSTEM_PREFIX,
XATTR_SYSTEM_PREFIX_LEN,
XATTR_POSIX_ACL_ACCESS,
strlen(XATTR_POSIX_ACL_ACCESS));
- if (ret)
- return ret;
} else if (namelen == SGI_ACL_DEFAULT_SIZE &&
strncmp(name, SGI_ACL_DEFAULT,
SGI_ACL_DEFAULT_SIZE) == 0) {
- int ret = __xfs_xattr_put_listent(
+ __xfs_xattr_put_listent(
context, XATTR_SYSTEM_PREFIX,
XATTR_SYSTEM_PREFIX_LEN,
XATTR_POSIX_ACL_DEFAULT,
strlen(XATTR_POSIX_ACL_DEFAULT));
- if (ret)
- return ret;
}
#endif
@@ -205,7 +201,7 @@ xfs_xattr_put_listent(
* see them.
*/
if (!capable(CAP_SYS_ADMIN))
- return 0;
+ return;
prefix = XATTR_TRUSTED_PREFIX;
prefix_len = XATTR_TRUSTED_PREFIX_LEN;
@@ -217,8 +213,9 @@ xfs_xattr_put_listent(
prefix_len = XATTR_USER_PREFIX_LEN;
}
- return __xfs_xattr_put_listent(context, prefix, prefix_len, name,
- namelen);
+ __xfs_xattr_put_listent(context, prefix, prefix_len, name,
+ namelen);
+ return;
}
ssize_t
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c1a524de67c5..4242c31ffaee 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -573,6 +573,8 @@ struct acpi_pci_root {
bool acpi_dma_supported(struct acpi_device *adev);
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
+void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+void acpi_dma_deconfigure(struct device *dev);
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
u64 address, bool check_children);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 31e1d639abed..9e3aa34341f4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -566,6 +566,7 @@
IRQCHIP_OF_MATCH_TABLE() \
ACPI_PROBE_TABLE(irqchip) \
ACPI_PROBE_TABLE(clksrc) \
+ ACPI_PROBE_TABLE(iort) \
EARLYCON_TABLE()
#define INIT_TEXT \
diff --git a/include/clocksource/pxa.h b/include/clocksource/pxa.h
index 1efbe5a66958..a9a0f03024a4 100644
--- a/include/clocksource/pxa.h
+++ b/include/clocksource/pxa.h
@@ -12,7 +12,6 @@
#ifndef _CLOCKSOURCE_PXA_H
#define _CLOCKSOURCE_PXA_H
-extern void pxa_timer_nodt_init(int irq, void __iomem *base,
- unsigned long clock_tick_rate);
+extern void pxa_timer_nodt_init(int irq, void __iomem *base);
#endif
diff --git a/include/dt-bindings/clock/r7s72100-clock.h b/include/dt-bindings/clock/r7s72100-clock.h
index 3cd813896d08..29e01ed10e74 100644
--- a/include/dt-bindings/clock/r7s72100-clock.h
+++ b/include/dt-bindings/clock/r7s72100-clock.h
@@ -28,6 +28,9 @@
/* MSTP7 */
#define R7S72100_CLK_ETHER 4
+/* MSTP8 */
+#define R7S72100_CLK_MMCIF 4
+
/* MSTP9 */
#define R7S72100_CLK_I2C0 7
#define R7S72100_CLK_I2C1 6
@@ -41,4 +44,8 @@
#define R7S72100_CLK_SPI3 4
#define R7S72100_CLK_SPI4 3
+/* MSTP12 */
+#define R7S72100_CLK_SDHI0 3
+#define R7S72100_CLK_SDHI1 2
+
#endif /* __DT_BINDINGS_CLOCK_R7S72100_H__ */
diff --git a/include/dt-bindings/clock/r8a7794-clock.h b/include/dt-bindings/clock/r8a7794-clock.h
index 9d02f5317c7c..88e64846cf37 100644
--- a/include/dt-bindings/clock/r8a7794-clock.h
+++ b/include/dt-bindings/clock/r8a7794-clock.h
@@ -20,8 +20,7 @@
#define R8A7794_CLK_QSPI 5
#define R8A7794_CLK_SDH 6
#define R8A7794_CLK_SD0 7
-#define R8A7794_CLK_Z 8
-#define R8A7794_CLK_RCAN 9
+#define R8A7794_CLK_RCAN 8
/* MSTP0 */
#define R8A7794_CLK_MSIOF0 0
diff --git a/include/dt-bindings/clock/stih415-clks.h b/include/dt-bindings/clock/stih415-clks.h
deleted file mode 100644
index d80caa68aebd..000000000000
--- a/include/dt-bindings/clock/stih415-clks.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * This header provides constants clk index STMicroelectronics
- * STiH415 SoC.
- */
-#ifndef _CLK_STIH415
-#define _CLK_STIH415
-
-/* CLOCKGEN A0 */
-#define CLK_ICN_REG 0
-#define CLK_ETH1_PHY 4
-
-/* CLOCKGEN A1 */
-#define CLK_ICN_IF_2 0
-#define CLK_GMAC0_PHY 3
-
-#endif
diff --git a/include/dt-bindings/clock/tegra186-clock.h b/include/dt-bindings/clock/tegra186-clock.h
new file mode 100644
index 000000000000..f73d32098f99
--- /dev/null
+++ b/include/dt-bindings/clock/tegra186-clock.h
@@ -0,0 +1,940 @@
+/** @file */
+
+#ifndef _MACH_T186_CLK_T186_H
+#define _MACH_T186_CLK_T186_H
+
+/**
+ * @defgroup clock_ids Clock Identifiers
+ * @{
+ * @defgroup extern_input external input clocks
+ * @{
+ * @def TEGRA186_CLK_OSC
+ * @def TEGRA186_CLK_CLK_32K
+ * @def TEGRA186_CLK_DTV_INPUT
+ * @def TEGRA186_CLK_SOR0_PAD_CLKOUT
+ * @def TEGRA186_CLK_SOR1_PAD_CLKOUT
+ * @def TEGRA186_CLK_I2S1_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S2_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S3_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S4_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S5_SYNC_INPUT
+ * @def TEGRA186_CLK_I2S6_SYNC_INPUT
+ * @def TEGRA186_CLK_SPDIFIN_SYNC_INPUT
+ * @}
+ *
+ * @defgroup extern_output external output clocks
+ * @{
+ * @def TEGRA186_CLK_EXTPERIPH1
+ * @def TEGRA186_CLK_EXTPERIPH2
+ * @def TEGRA186_CLK_EXTPERIPH3
+ * @def TEGRA186_CLK_EXTPERIPH4
+ * @}
+ *
+ * @defgroup display_clks display related clocks
+ * @{
+ * @def TEGRA186_CLK_CEC
+ * @def TEGRA186_CLK_DSIC
+ * @def TEGRA186_CLK_DSIC_LP
+ * @def TEGRA186_CLK_DSID
+ * @def TEGRA186_CLK_DSID_LP
+ * @def TEGRA186_CLK_DPAUX1
+ * @def TEGRA186_CLK_DPAUX
+ * @def TEGRA186_CLK_HDA2HDMICODEC
+ * @def TEGRA186_CLK_NVDISPLAY_DISP
+ * @def TEGRA186_CLK_NVDISPLAY_DSC
+ * @def TEGRA186_CLK_NVDISPLAY_P0
+ * @def TEGRA186_CLK_NVDISPLAY_P1
+ * @def TEGRA186_CLK_NVDISPLAY_P2
+ * @def TEGRA186_CLK_NVDISPLAYHUB
+ * @def TEGRA186_CLK_SOR_SAFE
+ * @def TEGRA186_CLK_SOR0
+ * @def TEGRA186_CLK_SOR0_OUT
+ * @def TEGRA186_CLK_SOR1
+ * @def TEGRA186_CLK_SOR1_OUT
+ * @def TEGRA186_CLK_DSI
+ * @def TEGRA186_CLK_MIPI_CAL
+ * @def TEGRA186_CLK_DSIA_LP
+ * @def TEGRA186_CLK_DSIB
+ * @def TEGRA186_CLK_DSIB_LP
+ * @}
+ *
+ * @defgroup camera_clks camera related clocks
+ * @{
+ * @def TEGRA186_CLK_NVCSI
+ * @def TEGRA186_CLK_NVCSILP
+ * @def TEGRA186_CLK_VI
+ * @}
+ *
+ * @defgroup audio_clks audio related clocks
+ * @{
+ * @def TEGRA186_CLK_ACLK
+ * @def TEGRA186_CLK_ADSP
+ * @def TEGRA186_CLK_ADSPNEON
+ * @def TEGRA186_CLK_AHUB
+ * @def TEGRA186_CLK_APE
+ * @def TEGRA186_CLK_APB2APE
+ * @def TEGRA186_CLK_AUD_MCLK
+ * @def TEGRA186_CLK_DMIC1
+ * @def TEGRA186_CLK_DMIC2
+ * @def TEGRA186_CLK_DMIC3
+ * @def TEGRA186_CLK_DMIC4
+ * @def TEGRA186_CLK_DSPK1
+ * @def TEGRA186_CLK_DSPK2
+ * @def TEGRA186_CLK_HDA
+ * @def TEGRA186_CLK_HDA2CODEC_2X
+ * @def TEGRA186_CLK_I2S1
+ * @def TEGRA186_CLK_I2S2
+ * @def TEGRA186_CLK_I2S3
+ * @def TEGRA186_CLK_I2S4
+ * @def TEGRA186_CLK_I2S5
+ * @def TEGRA186_CLK_I2S6
+ * @def TEGRA186_CLK_MAUD
+ * @def TEGRA186_CLK_PLL_A_OUT0
+ * @def TEGRA186_CLK_SPDIF_DOUBLER
+ * @def TEGRA186_CLK_SPDIF_IN
+ * @def TEGRA186_CLK_SPDIF_OUT
+ * @def TEGRA186_CLK_SYNC_DMIC1
+ * @def TEGRA186_CLK_SYNC_DMIC2
+ * @def TEGRA186_CLK_SYNC_DMIC3
+ * @def TEGRA186_CLK_SYNC_DMIC4
+ * @def TEGRA186_CLK_SYNC_DMIC5
+ * @def TEGRA186_CLK_SYNC_DSPK1
+ * @def TEGRA186_CLK_SYNC_DSPK2
+ * @def TEGRA186_CLK_SYNC_I2S1
+ * @def TEGRA186_CLK_SYNC_I2S2
+ * @def TEGRA186_CLK_SYNC_I2S3
+ * @def TEGRA186_CLK_SYNC_I2S4
+ * @def TEGRA186_CLK_SYNC_I2S5
+ * @def TEGRA186_CLK_SYNC_I2S6
+ * @def TEGRA186_CLK_SYNC_SPDIF
+ * @}
+ *
+ * @defgroup uart_clks UART clocks
+ * @{
+ * @def TEGRA186_CLK_AON_UART_FST_MIPI_CAL
+ * @def TEGRA186_CLK_UARTA
+ * @def TEGRA186_CLK_UARTB
+ * @def TEGRA186_CLK_UARTC
+ * @def TEGRA186_CLK_UARTD
+ * @def TEGRA186_CLK_UARTE
+ * @def TEGRA186_CLK_UARTF
+ * @def TEGRA186_CLK_UARTG
+ * @def TEGRA186_CLK_UART_FST_MIPI_CAL
+ * @}
+ *
+ * @defgroup i2c_clks I2C clocks
+ * @{
+ * @def TEGRA186_CLK_AON_I2C_SLOW
+ * @def TEGRA186_CLK_I2C1
+ * @def TEGRA186_CLK_I2C2
+ * @def TEGRA186_CLK_I2C3
+ * @def TEGRA186_CLK_I2C4
+ * @def TEGRA186_CLK_I2C5
+ * @def TEGRA186_CLK_I2C6
+ * @def TEGRA186_CLK_I2C8
+ * @def TEGRA186_CLK_I2C9
+ * @def TEGRA186_CLK_I2C1
+ * @def TEGRA186_CLK_I2C12
+ * @def TEGRA186_CLK_I2C13
+ * @def TEGRA186_CLK_I2C14
+ * @def TEGRA186_CLK_I2C_SLOW
+ * @def TEGRA186_CLK_VI_I2C
+ * @}
+ *
+ * @defgroup spi_clks SPI clocks
+ * @{
+ * @def TEGRA186_CLK_SPI1
+ * @def TEGRA186_CLK_SPI2
+ * @def TEGRA186_CLK_SPI3
+ * @def TEGRA186_CLK_SPI4
+ * @}
+ *
+ * @defgroup storage storage related clocks
+ * @{
+ * @def TEGRA186_CLK_SATA
+ * @def TEGRA186_CLK_SATA_OOB
+ * @def TEGRA186_CLK_SATA_IOBIST
+ * @def TEGRA186_CLK_SDMMC_LEGACY_TM
+ * @def TEGRA186_CLK_SDMMC1
+ * @def TEGRA186_CLK_SDMMC2
+ * @def TEGRA186_CLK_SDMMC3
+ * @def TEGRA186_CLK_SDMMC4
+ * @def TEGRA186_CLK_QSPI
+ * @def TEGRA186_CLK_QSPI_OUT
+ * @def TEGRA186_CLK_UFSDEV_REF
+ * @def TEGRA186_CLK_UFSHC
+ * @}
+ *
+ * @defgroup pwm_clks PWM clocks
+ * @{
+ * @def TEGRA186_CLK_PWM1
+ * @def TEGRA186_CLK_PWM2
+ * @def TEGRA186_CLK_PWM3
+ * @def TEGRA186_CLK_PWM4
+ * @def TEGRA186_CLK_PWM5
+ * @def TEGRA186_CLK_PWM6
+ * @def TEGRA186_CLK_PWM7
+ * @def TEGRA186_CLK_PWM8
+ * @}
+ *
+ * @defgroup plls PLLs and related clocks
+ * @{
+ * @def TEGRA186_CLK_PLLREFE_OUT_GATED
+ * @def TEGRA186_CLK_PLLREFE_OUT1
+ * @def TEGRA186_CLK_PLLD_OUT1
+ * @def TEGRA186_CLK_PLLP_OUT0
+ * @def TEGRA186_CLK_PLLP_OUT5
+ * @def TEGRA186_CLK_PLLA
+ * @def TEGRA186_CLK_PLLE_PWRSEQ
+ * @def TEGRA186_CLK_PLLA_OUT1
+ * @def TEGRA186_CLK_PLLREFE_REF
+ * @def TEGRA186_CLK_UPHY_PLL0_PWRSEQ
+ * @def TEGRA186_CLK_UPHY_PLL1_PWRSEQ
+ * @def TEGRA186_CLK_PLLREFE_PLLE_PASSTHROUGH
+ * @def TEGRA186_CLK_PLLREFE_PEX
+ * @def TEGRA186_CLK_PLLREFE_IDDQ
+ * @def TEGRA186_CLK_PLLC_OUT_AON
+ * @def TEGRA186_CLK_PLLC_OUT_ISP
+ * @def TEGRA186_CLK_PLLC_OUT_VE
+ * @def TEGRA186_CLK_PLLC4_OUT
+ * @def TEGRA186_CLK_PLLREFE_OUT
+ * @def TEGRA186_CLK_PLLREFE_PLL_REF
+ * @def TEGRA186_CLK_PLLE
+ * @def TEGRA186_CLK_PLLC
+ * @def TEGRA186_CLK_PLLP
+ * @def TEGRA186_CLK_PLLD
+ * @def TEGRA186_CLK_PLLD2
+ * @def TEGRA186_CLK_PLLREFE_VCO
+ * @def TEGRA186_CLK_PLLC2
+ * @def TEGRA186_CLK_PLLC3
+ * @def TEGRA186_CLK_PLLDP
+ * @def TEGRA186_CLK_PLLC4_VCO
+ * @def TEGRA186_CLK_PLLA1
+ * @def TEGRA186_CLK_PLLNVCSI
+ * @def TEGRA186_CLK_PLLDISPHUB
+ * @def TEGRA186_CLK_PLLD3
+ * @def TEGRA186_CLK_PLLBPMPCAM
+ * @def TEGRA186_CLK_PLLAON
+ * @def TEGRA186_CLK_PLLU
+ * @def TEGRA186_CLK_PLLC4_VCO_DIV2
+ * @def TEGRA186_CLK_PLL_REF
+ * @def TEGRA186_CLK_PLLREFE_OUT1_DIV5
+ * @def TEGRA186_CLK_UTMIP_PLL_PWRSEQ
+ * @def TEGRA186_CLK_PLL_U_48M
+ * @def TEGRA186_CLK_PLL_U_480M
+ * @def TEGRA186_CLK_PLLC4_OUT0
+ * @def TEGRA186_CLK_PLLC4_OUT1
+ * @def TEGRA186_CLK_PLLC4_OUT2
+ * @def TEGRA186_CLK_PLLC4_OUT_MUX
+ * @def TEGRA186_CLK_DFLLDISP_DIV
+ * @def TEGRA186_CLK_PLLDISPHUB_DIV
+ * @def TEGRA186_CLK_PLLP_DIV8
+ * @}
+ *
+ * @defgroup nafll_clks NAFLL clock sources
+ * @{
+ * @def TEGRA186_CLK_NAFLL_AXI_CBB
+ * @def TEGRA186_CLK_NAFLL_BCPU
+ * @def TEGRA186_CLK_NAFLL_BPMP
+ * @def TEGRA186_CLK_NAFLL_DISP
+ * @def TEGRA186_CLK_NAFLL_GPU
+ * @def TEGRA186_CLK_NAFLL_ISP
+ * @def TEGRA186_CLK_NAFLL_MCPU
+ * @def TEGRA186_CLK_NAFLL_NVDEC
+ * @def TEGRA186_CLK_NAFLL_NVENC
+ * @def TEGRA186_CLK_NAFLL_NVJPG
+ * @def TEGRA186_CLK_NAFLL_SCE
+ * @def TEGRA186_CLK_NAFLL_SE
+ * @def TEGRA186_CLK_NAFLL_TSEC
+ * @def TEGRA186_CLK_NAFLL_TSECB
+ * @def TEGRA186_CLK_NAFLL_VI
+ * @def TEGRA186_CLK_NAFLL_VIC
+ * @}
+ *
+ * @defgroup mphy MPHY related clocks
+ * @{
+ * @def TEGRA186_CLK_MPHY_L0_RX_SYMB
+ * @def TEGRA186_CLK_MPHY_L0_RX_LS_BIT
+ * @def TEGRA186_CLK_MPHY_L0_TX_SYMB
+ * @def TEGRA186_CLK_MPHY_L0_TX_LS_3XBIT
+ * @def TEGRA186_CLK_MPHY_L0_RX_ANA
+ * @def TEGRA186_CLK_MPHY_L1_RX_ANA
+ * @def TEGRA186_CLK_MPHY_IOBIST
+ * @def TEGRA186_CLK_MPHY_TX_1MHZ_REF
+ * @def TEGRA186_CLK_MPHY_CORE_PLL_FIXED
+ * @}
+ *
+ * @defgroup eavb EAVB related clocks
+ * @{
+ * @def TEGRA186_CLK_EQOS_AXI
+ * @def TEGRA186_CLK_EQOS_PTP_REF
+ * @def TEGRA186_CLK_EQOS_RX
+ * @def TEGRA186_CLK_EQOS_RX_INPUT
+ * @def TEGRA186_CLK_EQOS_TX
+ * @}
+ *
+ * @defgroup usb USB related clocks
+ * @{
+ * @def TEGRA186_CLK_PEX_USB_PAD0_MGMT
+ * @def TEGRA186_CLK_PEX_USB_PAD1_MGMT
+ * @def TEGRA186_CLK_HSIC_TRK
+ * @def TEGRA186_CLK_USB2_TRK
+ * @def TEGRA186_CLK_USB2_HSIC_TRK
+ * @def TEGRA186_CLK_XUSB_CORE_SS
+ * @def TEGRA186_CLK_XUSB_CORE_DEV
+ * @def TEGRA186_CLK_XUSB_FALCON
+ * @def TEGRA186_CLK_XUSB_FS
+ * @def TEGRA186_CLK_XUSB
+ * @def TEGRA186_CLK_XUSB_DEV
+ * @def TEGRA186_CLK_XUSB_HOST
+ * @def TEGRA186_CLK_XUSB_SS
+ * @}
+ *
+ * @defgroup bigblock compute block related clocks
+ * @{
+ * @def TEGRA186_CLK_GPCCLK
+ * @def TEGRA186_CLK_GPC2CLK
+ * @def TEGRA186_CLK_GPU
+ * @def TEGRA186_CLK_HOST1X
+ * @def TEGRA186_CLK_ISP
+ * @def TEGRA186_CLK_NVDEC
+ * @def TEGRA186_CLK_NVENC
+ * @def TEGRA186_CLK_NVJPG
+ * @def TEGRA186_CLK_SE
+ * @def TEGRA186_CLK_TSEC
+ * @def TEGRA186_CLK_TSECB
+ * @def TEGRA186_CLK_VIC
+ * @}
+ *
+ * @defgroup can CAN bus related clocks
+ * @{
+ * @def TEGRA186_CLK_CAN1
+ * @def TEGRA186_CLK_CAN1_HOST
+ * @def TEGRA186_CLK_CAN2
+ * @def TEGRA186_CLK_CAN2_HOST
+ * @}
+ *
+ * @defgroup system basic system clocks
+ * @{
+ * @def TEGRA186_CLK_ACTMON
+ * @def TEGRA186_CLK_AON_APB
+ * @def TEGRA186_CLK_AON_CPU_NIC
+ * @def TEGRA186_CLK_AON_NIC
+ * @def TEGRA186_CLK_AXI_CBB
+ * @def TEGRA186_CLK_BPMP_APB
+ * @def TEGRA186_CLK_BPMP_CPU_NIC
+ * @def TEGRA186_CLK_BPMP_NIC_RATE
+ * @def TEGRA186_CLK_CLK_M
+ * @def TEGRA186_CLK_EMC
+ * @def TEGRA186_CLK_MSS_ENCRYPT
+ * @def TEGRA186_CLK_SCE_APB
+ * @def TEGRA186_CLK_SCE_CPU_NIC
+ * @def TEGRA186_CLK_SCE_NIC
+ * @def TEGRA186_CLK_TSC
+ * @}
+ *
+ * @defgroup pcie_clks PCIe related clocks
+ * @{
+ * @def TEGRA186_CLK_AFI
+ * @def TEGRA186_CLK_PCIE
+ * @def TEGRA186_CLK_PCIE2_IOBIST
+ * @def TEGRA186_CLK_PCIERX0
+ * @def TEGRA186_CLK_PCIERX1
+ * @def TEGRA186_CLK_PCIERX2
+ * @def TEGRA186_CLK_PCIERX3
+ * @def TEGRA186_CLK_PCIERX4
+ * @}
+ */
+
+/** @brief output of gate CLK_ENB_FUSE */
+#define TEGRA186_CLK_FUSE 0
+/**
+ * @brief It's not what you think
+ * @details output of gate CLK_ENB_GPU. This output connects to the GPU
+ * pwrclk. @warning: This is almost certainly not the clock you think
+ * it is. If you're looking for the clock of the graphics engine, see
+ * TEGRA186_GPCCLK
+ */
+#define TEGRA186_CLK_GPU 1
+/** @brief output of gate CLK_ENB_PCIE */
+#define TEGRA186_CLK_PCIE 3
+/** @brief output of the divider IPFS_CLK_DIVISOR */
+#define TEGRA186_CLK_AFI 4
+/** @brief output of gate CLK_ENB_PCIE2_IOBIST */
+#define TEGRA186_CLK_PCIE2_IOBIST 5
+/** @brief output of gate CLK_ENB_PCIERX0*/
+#define TEGRA186_CLK_PCIERX0 6
+/** @brief output of gate CLK_ENB_PCIERX1*/
+#define TEGRA186_CLK_PCIERX1 7
+/** @brief output of gate CLK_ENB_PCIERX2*/
+#define TEGRA186_CLK_PCIERX2 8
+/** @brief output of gate CLK_ENB_PCIERX3*/
+#define TEGRA186_CLK_PCIERX3 9
+/** @brief output of gate CLK_ENB_PCIERX4*/
+#define TEGRA186_CLK_PCIERX4 10
+/** @brief output branch of PLL_C for ISP, controlled by gate CLK_ENB_PLLC_OUT_ISP */
+#define TEGRA186_CLK_PLLC_OUT_ISP 11
+/** @brief output branch of PLL_C for VI, controlled by gate CLK_ENB_PLLC_OUT_VE */
+#define TEGRA186_CLK_PLLC_OUT_VE 12
+/** @brief output branch of PLL_C for AON domain, controlled by gate CLK_ENB_PLLC_OUT_AON */
+#define TEGRA186_CLK_PLLC_OUT_AON 13
+/** @brief output of gate CLK_ENB_SOR_SAFE */
+#define TEGRA186_CLK_SOR_SAFE 39
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2S2 */
+#define TEGRA186_CLK_I2S2 42
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2S3 */
+#define TEGRA186_CLK_I2S3 43
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SPDF_IN */
+#define TEGRA186_CLK_SPDIF_IN 44
+/** @brief output of gate CLK_ENB_SPDIF_DOUBLER */
+#define TEGRA186_CLK_SPDIF_DOUBLER 45
+/** @clkdesc{spi_clks, out, mux, CLK_RST_CONTROLLER_CLK_SOURCE_SPI3} */
+#define TEGRA186_CLK_SPI3 46
+/** @clkdesc{i2c_clks, out, mux, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1} */
+#define TEGRA186_CLK_I2C1 47
+/** @clkdesc{i2c_clks, out, mux, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5} */
+#define TEGRA186_CLK_I2C5 48
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SPI1 */
+#define TEGRA186_CLK_SPI1 49
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_ISP */
+#define TEGRA186_CLK_ISP 50
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_VI */
+#define TEGRA186_CLK_VI 51
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 */
+#define TEGRA186_CLK_SDMMC1 52
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 */
+#define TEGRA186_CLK_SDMMC2 53
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 */
+#define TEGRA186_CLK_SDMMC4 54
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTA */
+#define TEGRA186_CLK_UARTA 55
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTB */
+#define TEGRA186_CLK_UARTB 56
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X */
+#define TEGRA186_CLK_HOST1X 57
+/**
+ * @brief controls the EMC clock frequency.
+ * @details Doing a clk_set_rate on this clock will select the
+ * appropriate clock source, program the source rate and execute a
+ * specific sequence to switch to the new clock source for both memory
+ * controllers. This can be used to control the balance between memory
+ * throughput and memory controller power.
+ */
+#define TEGRA186_CLK_EMC 58
+/* @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH4 */
+#define TEGRA186_CLK_EXTPERIPH4 73
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SPI4 */
+#define TEGRA186_CLK_SPI4 74
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 */
+#define TEGRA186_CLK_I2C3 75
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 */
+#define TEGRA186_CLK_SDMMC3 76
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTD */
+#define TEGRA186_CLK_UARTD 77
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2S1 */
+#define TEGRA186_CLK_I2S1 79
+/** output of gate CLK_ENB_DTV */
+#define TEGRA186_CLK_DTV 80
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_TSEC */
+#define TEGRA186_CLK_TSEC 81
+/** @brief output of gate CLK_ENB_DP2 */
+#define TEGRA186_CLK_DP2 82
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2S4 */
+#define TEGRA186_CLK_I2S4 84
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2S5 */
+#define TEGRA186_CLK_I2S5 85
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 */
+#define TEGRA186_CLK_I2C4 86
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AHUB */
+#define TEGRA186_CLK_AHUB 87
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_HDA2CODEC_2X */
+#define TEGRA186_CLK_HDA2CODEC_2X 88
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 */
+#define TEGRA186_CLK_EXTPERIPH1 89
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 */
+#define TEGRA186_CLK_EXTPERIPH2 90
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH3 */
+#define TEGRA186_CLK_EXTPERIPH3 91
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C_SLOW */
+#define TEGRA186_CLK_I2C_SLOW 92
+/** @brief output of the SOR1_CLK_SRC mux in CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 */
+#define TEGRA186_CLK_SOR1 93
+/** @brief output of gate CLK_ENB_CEC */
+#define TEGRA186_CLK_CEC 94
+/** @brief output of gate CLK_ENB_DPAUX1 */
+#define TEGRA186_CLK_DPAUX1 95
+/** @brief output of gate CLK_ENB_DPAUX */
+#define TEGRA186_CLK_DPAUX 96
+/** @brief output of the SOR0_CLK_SRC mux in CLK_RST_CONTROLLER_CLK_SOURCE_SOR0 */
+#define TEGRA186_CLK_SOR0 97
+/** @brief output of gate CLK_ENB_HDA2HDMICODEC */
+#define TEGRA186_CLK_HDA2HDMICODEC 98
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SATA */
+#define TEGRA186_CLK_SATA 99
+/** @brief output of gate CLK_ENB_SATA_OOB */
+#define TEGRA186_CLK_SATA_OOB 100
+/** @brief output of gate CLK_ENB_SATA_IOBIST */
+#define TEGRA186_CLK_SATA_IOBIST 101
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_HDA */
+#define TEGRA186_CLK_HDA 102
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SE */
+#define TEGRA186_CLK_SE 103
+/** @brief output of gate CLK_ENB_APB2APE */
+#define TEGRA186_CLK_APB2APE 104
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_APE */
+#define TEGRA186_CLK_APE 105
+/** @brief output of gate CLK_ENB_IQC1 */
+#define TEGRA186_CLK_IQC1 106
+/** @brief output of gate CLK_ENB_IQC2 */
+#define TEGRA186_CLK_IQC2 107
+/** divide by 2 version of TEGRA186_CLK_PLLREFE_VCO */
+#define TEGRA186_CLK_PLLREFE_OUT 108
+/** @brief output of gate CLK_ENB_PLLREFE_PLL_REF */
+#define TEGRA186_CLK_PLLREFE_PLL_REF 109
+/** @brief output of gate CLK_ENB_PLLC4_OUT */
+#define TEGRA186_CLK_PLLC4_OUT 110
+/** @brief output of mux xusb_core_clk_switch on page 67 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB 111
+/** controls xusb_dev_ce signal on page 66 and 67 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_DEV 112
+/** controls xusb_host_ce signal on page 67 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_HOST 113
+/** controls xusb_ss_ce signal on page 67 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_SS 114
+/** @brief output of gate CLK_ENB_DSI */
+#define TEGRA186_CLK_DSI 115
+/** @brief output of gate CLK_ENB_MIPI_CAL */
+#define TEGRA186_CLK_MIPI_CAL 116
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP */
+#define TEGRA186_CLK_DSIA_LP 117
+/** @brief output of gate CLK_ENB_DSIB */
+#define TEGRA186_CLK_DSIB 118
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DSIB_LP */
+#define TEGRA186_CLK_DSIB_LP 119
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DMIC1 */
+#define TEGRA186_CLK_DMIC1 122
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DMIC2 */
+#define TEGRA186_CLK_DMIC2 123
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AUD_MCLK */
+#define TEGRA186_CLK_AUD_MCLK 124
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 */
+#define TEGRA186_CLK_I2C6 125
+/**output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL */
+#define TEGRA186_CLK_UART_FST_MIPI_CAL 126
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_VIC */
+#define TEGRA186_CLK_VIC 127
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM */
+#define TEGRA186_CLK_SDMMC_LEGACY_TM 128
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC */
+#define TEGRA186_CLK_NVDEC 129
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG */
+#define TEGRA186_CLK_NVJPG 130
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVENC */
+#define TEGRA186_CLK_NVENC 131
+/** @brief output of the QSPI_CLK_SRC mux in CLK_RST_CONTROLLER_CLK_SOURCE_QSPI */
+#define TEGRA186_CLK_QSPI 132
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_VI_I2C */
+#define TEGRA186_CLK_VI_I2C 133
+/** @brief output of gate CLK_ENB_HSIC_TRK */
+#define TEGRA186_CLK_HSIC_TRK 134
+/** @brief output of gate CLK_ENB_USB2_TRK */
+#define TEGRA186_CLK_USB2_TRK 135
+/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_MAUD */
+#define TEGRA186_CLK_MAUD 136
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_TSECB */
+#define TEGRA186_CLK_TSECB 137
+/** @brief output of gate CLK_ENB_ADSP */
+#define TEGRA186_CLK_ADSP 138
+/** @brief output of gate CLK_ENB_ADSPNEON */
+#define TEGRA186_CLK_ADSPNEON 139
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_MPHY_L0_RX_LS_SYMB */
+#define TEGRA186_CLK_MPHY_L0_RX_SYMB 140
+/** @brief output of gate CLK_ENB_MPHY_L0_RX_LS_BIT */
+#define TEGRA186_CLK_MPHY_L0_RX_LS_BIT 141
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_MPHY_L0_TX_LS_SYMB */
+#define TEGRA186_CLK_MPHY_L0_TX_SYMB 142
+/** @brief output of gate CLK_ENB_MPHY_L0_TX_LS_3XBIT */
+#define TEGRA186_CLK_MPHY_L0_TX_LS_3XBIT 143
+/** @brief output of gate CLK_ENB_MPHY_L0_RX_ANA */
+#define TEGRA186_CLK_MPHY_L0_RX_ANA 144
+/** @brief output of gate CLK_ENB_MPHY_L1_RX_ANA */
+#define TEGRA186_CLK_MPHY_L1_RX_ANA 145
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_MPHY_IOBIST */
+#define TEGRA186_CLK_MPHY_IOBIST 146
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_MPHY_TX_1MHZ_REF */
+#define TEGRA186_CLK_MPHY_TX_1MHZ_REF 147
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_MPHY_CORE_PLL_FIXED */
+#define TEGRA186_CLK_MPHY_CORE_PLL_FIXED 148
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AXI_CBB */
+#define TEGRA186_CLK_AXI_CBB 149
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DMIC3 */
+#define TEGRA186_CLK_DMIC3 150
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DMIC4 */
+#define TEGRA186_CLK_DMIC4 151
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DSPK1 */
+#define TEGRA186_CLK_DSPK1 152
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DSPK2 */
+#define TEGRA186_CLK_DSPK2 153
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 */
+#define TEGRA186_CLK_I2S6 154
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAY_P0 */
+#define TEGRA186_CLK_NVDISPLAY_P0 155
+/** @brief output of the NVDISPLAY_DISP_CLK_SRC mux in CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAY_DISP */
+#define TEGRA186_CLK_NVDISPLAY_DISP 156
+/** @brief output of gate CLK_ENB_NVDISPLAY_DSC */
+#define TEGRA186_CLK_NVDISPLAY_DSC 157
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAYHUB */
+#define TEGRA186_CLK_NVDISPLAYHUB 158
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAY_P1 */
+#define TEGRA186_CLK_NVDISPLAY_P1 159
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAY_P2 */
+#define TEGRA186_CLK_NVDISPLAY_P2 160
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_TACH */
+#define TEGRA186_CLK_TACH 166
+/** @brief output of gate CLK_ENB_EQOS */
+#define TEGRA186_CLK_EQOS_AXI 167
+/** @brief output of gate CLK_ENB_EQOS_RX */
+#define TEGRA186_CLK_EQOS_RX 168
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UFSHC_CG_SYS */
+#define TEGRA186_CLK_UFSHC 178
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UFSDEV_REF */
+#define TEGRA186_CLK_UFSDEV_REF 179
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVCSI */
+#define TEGRA186_CLK_NVCSI 180
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_NVCSILP */
+#define TEGRA186_CLK_NVCSILP 181
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C7 */
+#define TEGRA186_CLK_I2C7 182
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C9 */
+#define TEGRA186_CLK_I2C9 183
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C12 */
+#define TEGRA186_CLK_I2C12 184
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C13 */
+#define TEGRA186_CLK_I2C13 185
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C14 */
+#define TEGRA186_CLK_I2C14 186
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM1 */
+#define TEGRA186_CLK_PWM1 187
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM2 */
+#define TEGRA186_CLK_PWM2 188
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM3 */
+#define TEGRA186_CLK_PWM3 189
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM5 */
+#define TEGRA186_CLK_PWM5 190
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM6 */
+#define TEGRA186_CLK_PWM6 191
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM7 */
+#define TEGRA186_CLK_PWM7 192
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM8 */
+#define TEGRA186_CLK_PWM8 193
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTE */
+#define TEGRA186_CLK_UARTE 194
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTF */
+#define TEGRA186_CLK_UARTF 195
+/** @deprecated */
+#define TEGRA186_CLK_DBGAPB 196
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_BPMP_CPU_NIC */
+#define TEGRA186_CLK_BPMP_CPU_NIC 197
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_BPMP_APB */
+#define TEGRA186_CLK_BPMP_APB 199
+/** @brief output of mux controlled by TEGRA186_CLK_SOC_ACTMON */
+#define TEGRA186_CLK_ACTMON 201
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AON_CPU_NIC */
+#define TEGRA186_CLK_AON_CPU_NIC 208
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_CAN1 */
+#define TEGRA186_CLK_CAN1 210
+/** @brief output of gate CLK_ENB_CAN1_HOST */
+#define TEGRA186_CLK_CAN1_HOST 211
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_CAN2 */
+#define TEGRA186_CLK_CAN2 212
+/** @brief output of gate CLK_ENB_CAN2_HOST */
+#define TEGRA186_CLK_CAN2_HOST 213
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AON_APB */
+#define TEGRA186_CLK_AON_APB 214
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTC */
+#define TEGRA186_CLK_UARTC 215
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_UARTG */
+#define TEGRA186_CLK_UARTG 216
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AON_UART_FST_MIPI_CAL */
+#define TEGRA186_CLK_AON_UART_FST_MIPI_CAL 217
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C2 */
+#define TEGRA186_CLK_I2C2 218
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C8 */
+#define TEGRA186_CLK_I2C8 219
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C10 */
+#define TEGRA186_CLK_I2C10 220
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AON_I2C_SLOW */
+#define TEGRA186_CLK_AON_I2C_SLOW 221
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SPI2 */
+#define TEGRA186_CLK_SPI2 222
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DMIC5 */
+#define TEGRA186_CLK_DMIC5 223
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_AON_TOUCH */
+#define TEGRA186_CLK_AON_TOUCH 224
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_PWM4 */
+#define TEGRA186_CLK_PWM4 225
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_TSC. This clock object is read only and is used for all timers in the system. */
+#define TEGRA186_CLK_TSC 226
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_MSS_ENCRYPT */
+#define TEGRA186_CLK_MSS_ENCRYPT 227
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SCE_CPU_NIC */
+#define TEGRA186_CLK_SCE_CPU_NIC 228
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SCE_APB */
+#define TEGRA186_CLK_SCE_APB 230
+/** @brief output of gate CLK_ENB_DSIC */
+#define TEGRA186_CLK_DSIC 231
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DSIC_LP */
+#define TEGRA186_CLK_DSIC_LP 232
+/** @brief output of gate CLK_ENB_DSID */
+#define TEGRA186_CLK_DSID 233
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_DSID_LP */
+#define TEGRA186_CLK_DSID_LP 234
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_PEX_SATA_USB_RX_BYP */
+#define TEGRA186_CLK_PEX_SATA_USB_RX_BYP 236
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_SPDIF_OUT */
+#define TEGRA186_CLK_SPDIF_OUT 238
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_EQOS_PTP_REF_CLK_0 */
+#define TEGRA186_CLK_EQOS_PTP_REF 239
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_EQOS_TX_CLK */
+#define TEGRA186_CLK_EQOS_TX 240
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK */
+#define TEGRA186_CLK_USB2_HSIC_TRK 241
+/** @brief output of mux xusb_ss_clk_switch on page 66 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_CORE_SS 242
+/** @brief output of mux xusb_core_dev_clk_switch on page 67 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_CORE_DEV 243
+/** @brief output of mux xusb_core_falcon_clk_switch on page 67 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_FALCON 244
+/** @brief output of mux xusb_fs_clk_switch on page 66 of T186_Clocks_IAS.doc */
+#define TEGRA186_CLK_XUSB_FS 245
+/** @brief output of the divider CLK_RST_CONTROLLER_PLLA_OUT */
+#define TEGRA186_CLK_PLL_A_OUT0 246
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S1 */
+#define TEGRA186_CLK_SYNC_I2S1 247
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S2 */
+#define TEGRA186_CLK_SYNC_I2S2 248
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S3 */
+#define TEGRA186_CLK_SYNC_I2S3 249
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S4 */
+#define TEGRA186_CLK_SYNC_I2S4 250
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S5 */
+#define TEGRA186_CLK_SYNC_I2S5 251
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S6 */
+#define TEGRA186_CLK_SYNC_I2S6 252
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DSPK1 */
+#define TEGRA186_CLK_SYNC_DSPK1 253
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DSPK2 */
+#define TEGRA186_CLK_SYNC_DSPK2 254
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DMIC1 */
+#define TEGRA186_CLK_SYNC_DMIC1 255
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DMIC2 */
+#define TEGRA186_CLK_SYNC_DMIC2 256
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DMIC3 */
+#define TEGRA186_CLK_SYNC_DMIC3 257
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DMIC4 */
+#define TEGRA186_CLK_SYNC_DMIC4 259
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_SPDIF */
+#define TEGRA186_CLK_SYNC_SPDIF 260
+/** @brief output of gate CLK_ENB_PLLREFE_OUT */
+#define TEGRA186_CLK_PLLREFE_OUT_GATED 261
+/** @brief output of the divider PLLREFE_DIVP in CLK_RST_CONTROLLER_PLLREFE_BASE. PLLREFE has 2 outputs:
+ * * VCO/pdiv defined by this clock object
+ * * VCO/2 defined by TEGRA186_CLK_PLLREFE_OUT
+ */
+#define TEGRA186_CLK_PLLREFE_OUT1 262
+#define TEGRA186_CLK_PLLD_OUT1 267
+/** @brief output of the divider PLLP_DIVP in CLK_RST_CONTROLLER_PLLP_BASE */
+#define TEGRA186_CLK_PLLP_OUT0 269
+/** @brief output of the divider CLK_RST_CONTROLLER_PLLP_OUTC */
+#define TEGRA186_CLK_PLLP_OUT5 270
+/** PLL controlled by CLK_RST_CONTROLLER_PLLA_BASE for use by audio clocks */
+#define TEGRA186_CLK_PLLA 271
+/** @brief output of mux controlled by CLK_RST_CONTROLLER_ACLK_BURST_POLICY divided by the divider controlled by ACLK_CLK_DIVISOR in CLK_RST_CONTROLLER_SUPER_ACLK_DIVIDER */
+#define TEGRA186_CLK_ACLK 273
+/** fixed 48MHz clock divided down from TEGRA186_CLK_PLL_U */
+#define TEGRA186_CLK_PLL_U_48M 274
+/** fixed 480MHz clock divided down from TEGRA186_CLK_PLL_U */
+#define TEGRA186_CLK_PLL_U_480M 275
+/** @brief output of the divider PLLC4_DIVP in CLK_RST_CONTROLLER_PLLC4_BASE. Output frequency is TEGRA186_CLK_PLLC4_VCO/PLLC4_DIVP */
+#define TEGRA186_CLK_PLLC4_OUT0 276
+/** fixed /3 divider. Output frequency of this clock is TEGRA186_CLK_PLLC4_VCO/3 */
+#define TEGRA186_CLK_PLLC4_OUT1 277
+/** fixed /5 divider. Output frequency of this clock is TEGRA186_CLK_PLLC4_VCO/5 */
+#define TEGRA186_CLK_PLLC4_OUT2 278
+/** @brief output of mux controlled by PLLC4_CLK_SEL in CLK_RST_CONTROLLER_PLLC4_MISC1 */
+#define TEGRA186_CLK_PLLC4_OUT_MUX 279
+/** @brief output of divider NVDISPLAY_DISP_CLK_DIVISOR in CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAY_DISP when DFLLDISP_DIV is selected in NVDISPLAY_DISP_CLK_SRC */
+#define TEGRA186_CLK_DFLLDISP_DIV 284
+/** @brief output of divider NVDISPLAY_DISP_CLK_DIVISOR in CLK_RST_CONTROLLER_CLK_SOURCE_NVDISPLAY_DISP when PLLDISPHUB_DIV is selected in NVDISPLAY_DISP_CLK_SRC */
+#define TEGRA186_CLK_PLLDISPHUB_DIV 285
+/** fixed /8 divider which is used as the input for TEGRA186_CLK_SOR_SAFE */
+#define TEGRA186_CLK_PLLP_DIV8 286
+/** @brief output of divider CLK_RST_CONTROLLER_BPMP_NIC_RATE */
+#define TEGRA186_CLK_BPMP_NIC 287
+/** @brief output of the divider CLK_RST_CONTROLLER_PLLA1_OUT1 */
+#define TEGRA186_CLK_PLL_A_OUT1 288
+/** @deprecated */
+#define TEGRA186_CLK_GPC2CLK 289
+/** A fake clock which must be enabled during KFUSE read operations to ensure adequate VDD_CORE voltage. */
+#define TEGRA186_CLK_KFUSE 293
+/**
+ * @brief controls the PLLE hardware sequencer.
+ * @details This clock only has enable and disable methods. When the
+ * PLLE hw sequencer is enabled, PLLE, will be enabled or disabled by
+ * hw based on the control signals from the PCIe, SATA and XUSB
+ * clocks. When the PLLE hw sequencer is disabled, the state of PLLE
+ * is controlled by sw using clk_enable/clk_disable on
+ * TEGRA186_CLK_PLLE.
+ */
+#define TEGRA186_CLK_PLLE_PWRSEQ 294
+/** fixed 60MHz clock divided down from, TEGRA186_CLK_PLL_U */
+#define TEGRA186_CLK_PLLREFE_REF 295
+/** @brief output of mux controlled by SOR0_CLK_SEL0 and SOR0_CLK_SEL1 in CLK_RST_CONTROLLER_CLK_SOURCE_SOR0 */
+#define TEGRA186_CLK_SOR0_OUT 296
+/** @brief output of mux controlled by SOR1_CLK_SEL0 and SOR1_CLK_SEL1 in CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 */
+#define TEGRA186_CLK_SOR1_OUT 297
+/** @brief fixed /5 divider. Output frequency of this clock is TEGRA186_CLK_PLLREFE_OUT1/5. Used as input for TEGRA186_CLK_EQOS_AXI */
+#define TEGRA186_CLK_PLLREFE_OUT1_DIV5 298
+/** @brief controls the UTMIP_PLL (aka PLLU) hardware sqeuencer */
+#define TEGRA186_CLK_UTMIP_PLL_PWRSEQ 301
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_PEX_USB_PAD_PLL0_MGMT */
+#define TEGRA186_CLK_PEX_USB_PAD0_MGMT 302
+/** @brief output of the divider CLK_RST_CONTROLLER_CLK_SOURCE_PEX_USB_PAD_PLL1_MGMT */
+#define TEGRA186_CLK_PEX_USB_PAD1_MGMT 303
+/** @brief controls the UPHY_PLL0 hardware sqeuencer */
+#define TEGRA186_CLK_UPHY_PLL0_PWRSEQ 304
+/** @brief controls the UPHY_PLL1 hardware sqeuencer */
+#define TEGRA186_CLK_UPHY_PLL1_PWRSEQ 305
+/** @brief control for PLLREFE_IDDQ in CLK_RST_CONTROLLER_PLLREFE_MISC so the bypass output even be used when the PLL is disabled */
+#define TEGRA186_CLK_PLLREFE_PLLE_PASSTHROUGH 306
+/** @brief output of the mux controlled by PLLREFE_SEL_CLKIN_PEX in CLK_RST_CONTROLLER_PLLREFE_MISC */
+#define TEGRA186_CLK_PLLREFE_PEX 307
+/** @brief control for PLLREFE_IDDQ in CLK_RST_CONTROLLER_PLLREFE_MISC to turn on the PLL when enabled */
+#define TEGRA186_CLK_PLLREFE_IDDQ 308
+/** @brief output of the divider QSPI_CLK_DIV2_SEL in CLK_RST_CONTROLLER_CLK_SOURCE_QSPI */
+#define TEGRA186_CLK_QSPI_OUT 309
+/**
+ * @brief GPC2CLK-div-2
+ * @details fixed /2 divider. Output frequency is
+ * TEGRA186_CLK_GPC2CLK/2. The frequency of this clock is the
+ * frequency at which the GPU graphics engine runs. */
+#define TEGRA186_CLK_GPCCLK 310
+/** @brief output of divider CLK_RST_CONTROLLER_AON_NIC_RATE */
+#define TEGRA186_CLK_AON_NIC 450
+/** @brief output of divider CLK_RST_CONTROLLER_SCE_NIC_RATE */
+#define TEGRA186_CLK_SCE_NIC 451
+/** Fixed 100MHz PLL for PCIe, SATA and superspeed USB */
+#define TEGRA186_CLK_PLLE 512
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLC_BASE */
+#define TEGRA186_CLK_PLLC 513
+/** Fixed 408MHz PLL for use by peripheral clocks */
+#define TEGRA186_CLK_PLLP 516
+/** @deprecated */
+#define TEGRA186_CLK_PLL_P TEGRA186_CLK_PLLP
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLD_BASE for use by DSI */
+#define TEGRA186_CLK_PLLD 518
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLD2_BASE for use by HDMI or DP */
+#define TEGRA186_CLK_PLLD2 519
+/**
+ * @brief PLL controlled by CLK_RST_CONTROLLER_PLLREFE_BASE.
+ * @details Note that this clock only controls the VCO output, before
+ * the post-divider. See TEGRA186_CLK_PLLREFE_OUT1 for more
+ * information.
+ */
+#define TEGRA186_CLK_PLLREFE_VCO 520
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLC2_BASE */
+#define TEGRA186_CLK_PLLC2 521
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLC3_BASE */
+#define TEGRA186_CLK_PLLC3 522
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLDP_BASE for use as the DP link clock */
+#define TEGRA186_CLK_PLLDP 523
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLC4_BASE */
+#define TEGRA186_CLK_PLLC4_VCO 524
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLA1_BASE for use by audio clocks */
+#define TEGRA186_CLK_PLLA1 525
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLNVCSI_BASE */
+#define TEGRA186_CLK_PLLNVCSI 526
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLDISPHUB_BASE */
+#define TEGRA186_CLK_PLLDISPHUB 527
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLD3_BASE for use by HDMI or DP */
+#define TEGRA186_CLK_PLLD3 528
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLBPMPCAM_BASE */
+#define TEGRA186_CLK_PLLBPMPCAM 531
+/** @brief PLL controlled by CLK_RST_CONTROLLER_PLLAON_BASE for use by IP blocks in the AON domain */
+#define TEGRA186_CLK_PLLAON 532
+/** Fixed frequency 960MHz PLL for USB and EAVB */
+#define TEGRA186_CLK_PLLU 533
+/** fixed /2 divider. Output frequency is TEGRA186_CLK_PLLC4_VCO/2 */
+#define TEGRA186_CLK_PLLC4_VCO_DIV2 535
+/** @brief NAFLL clock source for AXI_CBB */
+#define TEGRA186_CLK_NAFLL_AXI_CBB 564
+/** @brief NAFLL clock source for BPMP */
+#define TEGRA186_CLK_NAFLL_BPMP 565
+/** @brief NAFLL clock source for ISP */
+#define TEGRA186_CLK_NAFLL_ISP 566
+/** @brief NAFLL clock source for NVDEC */
+#define TEGRA186_CLK_NAFLL_NVDEC 567
+/** @brief NAFLL clock source for NVENC */
+#define TEGRA186_CLK_NAFLL_NVENC 568
+/** @brief NAFLL clock source for NVJPG */
+#define TEGRA186_CLK_NAFLL_NVJPG 569
+/** @brief NAFLL clock source for SCE */
+#define TEGRA186_CLK_NAFLL_SCE 570
+/** @brief NAFLL clock source for SE */
+#define TEGRA186_CLK_NAFLL_SE 571
+/** @brief NAFLL clock source for TSEC */
+#define TEGRA186_CLK_NAFLL_TSEC 572
+/** @brief NAFLL clock source for TSECB */
+#define TEGRA186_CLK_NAFLL_TSECB 573
+/** @brief NAFLL clock source for VI */
+#define TEGRA186_CLK_NAFLL_VI 574
+/** @brief NAFLL clock source for VIC */
+#define TEGRA186_CLK_NAFLL_VIC 575
+/** @brief NAFLL clock source for DISP */
+#define TEGRA186_CLK_NAFLL_DISP 576
+/** @brief NAFLL clock source for GPU */
+#define TEGRA186_CLK_NAFLL_GPU 577
+/** @brief NAFLL clock source for M-CPU cluster */
+#define TEGRA186_CLK_NAFLL_MCPU 578
+/** @brief NAFLL clock source for B-CPU cluster */
+#define TEGRA186_CLK_NAFLL_BCPU 579
+/** @brief input from Tegra's CLK_32K_IN pad */
+#define TEGRA186_CLK_CLK_32K 608
+/** @brief output of divider CLK_RST_CONTROLLER_CLK_M_DIVIDE */
+#define TEGRA186_CLK_CLK_M 609
+/** @brief output of divider PLL_REF_DIV in CLK_RST_CONTROLLER_OSC_CTRL */
+#define TEGRA186_CLK_PLL_REF 610
+/** @brief input from Tegra's XTAL_IN */
+#define TEGRA186_CLK_OSC 612
+/** @brief clock recovered from EAVB input */
+#define TEGRA186_CLK_EQOS_RX_INPUT 613
+/** @brief clock recovered from DTV input */
+#define TEGRA186_CLK_DTV_INPUT 614
+/** @brief SOR0 brick output which feeds into SOR0_CLK_SEL mux in CLK_RST_CONTROLLER_CLK_SOURCE_SOR0*/
+#define TEGRA186_CLK_SOR0_PAD_CLKOUT 615
+/** @brief SOR1 brick output which feeds into SOR1_CLK_SEL mux in CLK_RST_CONTROLLER_CLK_SOURCE_SOR1*/
+#define TEGRA186_CLK_SOR1_PAD_CLKOUT 616
+/** @brief clock recovered from I2S1 input */
+#define TEGRA186_CLK_I2S1_SYNC_INPUT 617
+/** @brief clock recovered from I2S2 input */
+#define TEGRA186_CLK_I2S2_SYNC_INPUT 618
+/** @brief clock recovered from I2S3 input */
+#define TEGRA186_CLK_I2S3_SYNC_INPUT 619
+/** @brief clock recovered from I2S4 input */
+#define TEGRA186_CLK_I2S4_SYNC_INPUT 620
+/** @brief clock recovered from I2S5 input */
+#define TEGRA186_CLK_I2S5_SYNC_INPUT 621
+/** @brief clock recovered from I2S6 input */
+#define TEGRA186_CLK_I2S6_SYNC_INPUT 622
+/** @brief clock recovered from SPDIFIN input */
+#define TEGRA186_CLK_SPDIFIN_SYNC_INPUT 623
+
+/**
+ * @brief subject to change
+ * @details maximum clock identifier value plus one.
+ */
+#define TEGRA186_CLK_CLK_MAX 624
+
+/** @} */
+
+#endif
diff --git a/include/dt-bindings/mailbox/tegra186-hsp.h b/include/dt-bindings/mailbox/tegra186-hsp.h
new file mode 100644
index 000000000000..f5d66e5f5f10
--- /dev/null
+++ b/include/dt-bindings/mailbox/tegra186-hsp.h
@@ -0,0 +1,24 @@
+/*
+ * This header provides constants for binding nvidia,tegra186-hsp.
+ */
+
+#ifndef _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+#define _DT_BINDINGS_MAILBOX_TEGRA186_HSP_H
+
+/*
+ * These define the type of mailbox that is to be used (doorbell, shared
+ * mailbox, shared semaphore or arbitrated semaphore).
+ */
+#define TEGRA_HSP_MBOX_TYPE_DB 0x0
+#define TEGRA_HSP_MBOX_TYPE_SM 0x1
+#define TEGRA_HSP_MBOX_TYPE_SS 0x2
+#define TEGRA_HSP_MBOX_TYPE_AS 0x3
+
+/*
+ * These defines represent the bit associated with the given master ID in the
+ * doorbell registers.
+ */
+#define TEGRA_HSP_DB_MASTER_CCPLEX 17
+#define TEGRA_HSP_DB_MASTER_BPMP 19
+
+#endif
diff --git a/include/dt-bindings/mfd/tps65217.h b/include/dt-bindings/mfd/tps65217.h
new file mode 100644
index 000000000000..cafb9e60cf12
--- /dev/null
+++ b/include/dt-bindings/mfd/tps65217.h
@@ -0,0 +1,26 @@
+/*
+ * This header provides macros for TI TPS65217 DT bindings.
+ *
+ * Copyright (C) 2016 Texas Instruments
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DT_BINDINGS_TPS65217_H__
+#define __DT_BINDINGS_TPS65217_H__
+
+#define TPS65217_IRQ_USB 0
+#define TPS65217_IRQ_AC 1
+#define TPS65217_IRQ_PB 2
+
+#endif
diff --git a/include/dt-bindings/pinctrl/bcm2835.h b/include/dt-bindings/pinctrl/bcm2835.h
index 6f0bc37af39c..e4e4fdf5d38f 100644
--- a/include/dt-bindings/pinctrl/bcm2835.h
+++ b/include/dt-bindings/pinctrl/bcm2835.h
@@ -24,4 +24,9 @@
#define BCM2835_FSEL_ALT2 6
#define BCM2835_FSEL_ALT3 7
+/* brcm,pull property */
+#define BCM2835_PUD_OFF 0
+#define BCM2835_PUD_DOWN 1
+#define BCM2835_PUD_UP 2
+
#endif /* __DT_BINDINGS_PINCTRL_BCM2835_H__ */
diff --git a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h
index aafa76cb569d..d33f17c8a515 100644
--- a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h
+++ b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h
@@ -89,6 +89,10 @@
#define PMA8084_GPIO_S4 2
#define PMA8084_GPIO_L6 3
+#define PM8994_GPIO_VPH 0
+#define PM8994_GPIO_S4 2
+#define PM8994_GPIO_L12 3
+
/* To be used with "function" */
#define PMIC_GPIO_FUNC_NORMAL "normal"
#define PMIC_GPIO_FUNC_PAIRED "paired"
diff --git a/include/dt-bindings/pinctrl/qcom,pmic-mpp.h b/include/dt-bindings/pinctrl/qcom,pmic-mpp.h
index a15c1704d0ec..2e360d8f7801 100644
--- a/include/dt-bindings/pinctrl/qcom,pmic-mpp.h
+++ b/include/dt-bindings/pinctrl/qcom,pmic-mpp.h
@@ -65,6 +65,12 @@
#define PMA8084_MPP_S4 2
#define PMA8084_MPP_L6 3
+#define PM8994_MPP_VPH 0
+/* Only supported for MPP_05-MPP_08 */
+#define PM8994_MPP_L19 1
+#define PM8994_MPP_S4 2
+#define PM8994_MPP_L12 3
+
/*
* Analog Input - Set the source for analog input.
* To be used with "qcom,amux-route" property
diff --git a/include/dt-bindings/pinctrl/rockchip.h b/include/dt-bindings/pinctrl/rockchip.h
index 743e66a95e13..aaec8baaa354 100644
--- a/include/dt-bindings/pinctrl/rockchip.h
+++ b/include/dt-bindings/pinctrl/rockchip.h
@@ -25,6 +25,39 @@
#define RK_GPIO4 4
#define RK_GPIO6 6
+#define RK_PA0 0
+#define RK_PA1 1
+#define RK_PA2 2
+#define RK_PA3 3
+#define RK_PA4 4
+#define RK_PA5 5
+#define RK_PA6 6
+#define RK_PA7 7
+#define RK_PB0 8
+#define RK_PB1 9
+#define RK_PB2 10
+#define RK_PB3 11
+#define RK_PB4 12
+#define RK_PB5 13
+#define RK_PB6 14
+#define RK_PB7 15
+#define RK_PC0 16
+#define RK_PC1 17
+#define RK_PC2 18
+#define RK_PC3 19
+#define RK_PC4 20
+#define RK_PC5 21
+#define RK_PC6 22
+#define RK_PC7 23
+#define RK_PD0 24
+#define RK_PD1 25
+#define RK_PD2 26
+#define RK_PD3 27
+#define RK_PD4 28
+#define RK_PD5 29
+#define RK_PD6 30
+#define RK_PD7 31
+
#define RK_FUNC_GPIO 0
#define RK_FUNC_1 1
#define RK_FUNC_2 2
diff --git a/include/dt-bindings/power/mt2701-power.h b/include/dt-bindings/power/mt2701-power.h
new file mode 100644
index 000000000000..64cc826d642c
--- /dev/null
+++ b/include/dt-bindings/power/mt2701-power.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT2701_POWER_H
+#define _DT_BINDINGS_POWER_MT2701_POWER_H
+
+#define MT2701_POWER_DOMAIN_CONN 0
+#define MT2701_POWER_DOMAIN_DISP 1
+#define MT2701_POWER_DOMAIN_MFG 2
+#define MT2701_POWER_DOMAIN_VDEC 3
+#define MT2701_POWER_DOMAIN_ISP 4
+#define MT2701_POWER_DOMAIN_BDP 5
+#define MT2701_POWER_DOMAIN_ETH 6
+#define MT2701_POWER_DOMAIN_HIF 7
+#define MT2701_POWER_DOMAIN_IFR_MSC 8
+
+#endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */
diff --git a/include/dt-bindings/power/r8a7743-sysc.h b/include/dt-bindings/power/r8a7743-sysc.h
new file mode 100644
index 000000000000..61cfbb2907ea
--- /dev/null
+++ b/include/dt-bindings/power/r8a7743-sysc.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Cogent Embedded Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A7743_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A7743_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A7743_PD_CA15_CPU0 0
+#define R8A7743_PD_CA15_CPU1 1
+#define R8A7743_PD_CA15_SCU 12
+#define R8A7743_PD_SGX 20
+
+/* Always-on power area */
+#define R8A7743_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_R8A7743_SYSC_H__ */
diff --git a/include/dt-bindings/power/r8a7745-sysc.h b/include/dt-bindings/power/r8a7745-sysc.h
new file mode 100644
index 000000000000..1844c1171c04
--- /dev/null
+++ b/include/dt-bindings/power/r8a7745-sysc.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Cogent Embedded Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A7745_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A7745_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A7745_PD_CA7_CPU0 5
+#define R8A7745_PD_CA7_CPU1 6
+#define R8A7745_PD_SGX 20
+#define R8A7745_PD_CA7_SCU 21
+
+/* Always-on power area */
+#define R8A7745_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_R8A7745_SYSC_H__ */
diff --git a/include/dt-bindings/power/tegra186-powergate.h b/include/dt-bindings/power/tegra186-powergate.h
new file mode 100644
index 000000000000..388d6e228dc8
--- /dev/null
+++ b/include/dt-bindings/power/tegra186-powergate.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DT_BINDINGS_POWER_TEGRA186_POWERGATE_H
+#define _DT_BINDINGS_POWER_TEGRA186_POWERGATE_H
+
+#define TEGRA186_POWER_DOMAIN_AUD 0
+#define TEGRA186_POWER_DOMAIN_DFD 1
+#define TEGRA186_POWER_DOMAIN_DISP 2
+#define TEGRA186_POWER_DOMAIN_DISPB 3
+#define TEGRA186_POWER_DOMAIN_DISPC 4
+#define TEGRA186_POWER_DOMAIN_ISPA 5
+#define TEGRA186_POWER_DOMAIN_NVDEC 6
+#define TEGRA186_POWER_DOMAIN_NVJPG 7
+#define TEGRA186_POWER_DOMAIN_MPE 8
+#define TEGRA186_POWER_DOMAIN_PCX 9
+#define TEGRA186_POWER_DOMAIN_SAX 10
+#define TEGRA186_POWER_DOMAIN_VE 11
+#define TEGRA186_POWER_DOMAIN_VIC 12
+#define TEGRA186_POWER_DOMAIN_XUSBA 13
+#define TEGRA186_POWER_DOMAIN_XUSBB 14
+#define TEGRA186_POWER_DOMAIN_XUSBC 15
+#define TEGRA186_POWER_DOMAIN_GPU 43
+#define TEGRA186_POWER_DOMAIN_MAX 44
+
+#endif
diff --git a/include/dt-bindings/reset/oxsemi,ox810se.h b/include/dt-bindings/reset/oxsemi,ox810se.h
new file mode 100644
index 000000000000..960c26e4504a
--- /dev/null
+++ b/include/dt-bindings/reset/oxsemi,ox810se.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DT_RESET_OXSEMI_OX810SE_H
+#define DT_RESET_OXSEMI_OX810SE_H
+
+#define RESET_ARM 0
+#define RESET_COPRO 1
+/* Reserved 2 */
+/* Reserved 3 */
+#define RESET_USBHS 4
+#define RESET_USBHSPHY 5
+#define RESET_MAC 6
+#define RESET_PCI 7
+#define RESET_DMA 8
+#define RESET_DPE 9
+#define RESET_DDR 10
+#define RESET_SATA 11
+#define RESET_SATA_LINK 12
+#define RESET_SATA_PHY 13
+ /* Reserved 14 */
+#define RESET_NAND 15
+#define RESET_GPIO 16
+#define RESET_UART1 17
+#define RESET_UART2 18
+#define RESET_MISC 19
+#define RESET_I2S 20
+#define RESET_AHB_MON 21
+#define RESET_UART3 22
+#define RESET_UART4 23
+#define RESET_SGDMA 24
+/* Reserved 25 */
+/* Reserved 26 */
+/* Reserved 27 */
+/* Reserved 28 */
+/* Reserved 29 */
+/* Reserved 30 */
+#define RESET_BUS 31
+
+#endif /* DT_RESET_OXSEMI_OX810SE_H */
diff --git a/include/dt-bindings/reset/oxsemi,ox820.h b/include/dt-bindings/reset/oxsemi,ox820.h
new file mode 100644
index 000000000000..cc6797bf01d8
--- /dev/null
+++ b/include/dt-bindings/reset/oxsemi,ox820.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DT_RESET_OXSEMI_OX820_H
+#define DT_RESET_OXSEMI_OX820_H
+
+#define RESET_SCU 0
+#define RESET_LEON 1
+#define RESET_ARM0 2
+#define RESET_ARM1 3
+#define RESET_USBHS 4
+#define RESET_USBPHYA 5
+#define RESET_MAC 6
+#define RESET_PCIEA 7
+#define RESET_SGDMA 8
+#define RESET_CIPHER 9
+#define RESET_DDR 10
+#define RESET_SATA 11
+#define RESET_SATA_LINK 12
+#define RESET_SATA_PHY 13
+#define RESET_PCIEPHY 14
+#define RESET_NAND 15
+#define RESET_GPIO 16
+#define RESET_UART1 17
+#define RESET_UART2 18
+#define RESET_MISC 19
+#define RESET_I2S 20
+#define RESET_SD 21
+#define RESET_MAC_2 22
+#define RESET_PCIEB 23
+#define RESET_VIDEO 24
+#define RESET_DDR_PHY 25
+#define RESET_USBPHYB 26
+#define RESET_USBDEV 27
+/* Reserved 29 */
+#define RESET_ARMDBG 29
+#define RESET_PLLA 30
+#define RESET_PLLB 31
+
+#endif /* DT_RESET_OXSEMI_OX820_H */
diff --git a/include/dt-bindings/reset/tegra186-reset.h b/include/dt-bindings/reset/tegra186-reset.h
new file mode 100644
index 000000000000..8a184e357955
--- /dev/null
+++ b/include/dt-bindings/reset/tegra186-reset.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ABI_MACH_T186_RESET_T186_H_
+#define _ABI_MACH_T186_RESET_T186_H_
+
+
+#define TEGRA186_RESET_ACTMON 0
+#define TEGRA186_RESET_AFI 1
+#define TEGRA186_RESET_CEC 2
+#define TEGRA186_RESET_CSITE 3
+#define TEGRA186_RESET_DP2 4
+#define TEGRA186_RESET_DPAUX 5
+#define TEGRA186_RESET_DSI 6
+#define TEGRA186_RESET_DSIB 7
+#define TEGRA186_RESET_DTV 8
+#define TEGRA186_RESET_DVFS 9
+#define TEGRA186_RESET_ENTROPY 10
+#define TEGRA186_RESET_EXTPERIPH1 11
+#define TEGRA186_RESET_EXTPERIPH2 12
+#define TEGRA186_RESET_EXTPERIPH3 13
+#define TEGRA186_RESET_GPU 14
+#define TEGRA186_RESET_HDA 15
+#define TEGRA186_RESET_HDA2CODEC_2X 16
+#define TEGRA186_RESET_HDA2HDMICODEC 17
+#define TEGRA186_RESET_HOST1X 18
+#define TEGRA186_RESET_I2C1 19
+#define TEGRA186_RESET_I2C2 20
+#define TEGRA186_RESET_I2C3 21
+#define TEGRA186_RESET_I2C4 22
+#define TEGRA186_RESET_I2C5 23
+#define TEGRA186_RESET_I2C6 24
+#define TEGRA186_RESET_ISP 25
+#define TEGRA186_RESET_KFUSE 26
+#define TEGRA186_RESET_LA 27
+#define TEGRA186_RESET_MIPI_CAL 28
+#define TEGRA186_RESET_PCIE 29
+#define TEGRA186_RESET_PCIEXCLK 30
+#define TEGRA186_RESET_SATA 31
+#define TEGRA186_RESET_SATACOLD 32
+#define TEGRA186_RESET_SDMMC1 33
+#define TEGRA186_RESET_SDMMC2 34
+#define TEGRA186_RESET_SDMMC3 35
+#define TEGRA186_RESET_SDMMC4 36
+#define TEGRA186_RESET_SE 37
+#define TEGRA186_RESET_SOC_THERM 38
+#define TEGRA186_RESET_SOR0 39
+#define TEGRA186_RESET_SPI1 40
+#define TEGRA186_RESET_SPI2 41
+#define TEGRA186_RESET_SPI3 42
+#define TEGRA186_RESET_SPI4 43
+#define TEGRA186_RESET_TMR 44
+#define TEGRA186_RESET_TRIG_SYS 45
+#define TEGRA186_RESET_TSEC 46
+#define TEGRA186_RESET_UARTA 47
+#define TEGRA186_RESET_UARTB 48
+#define TEGRA186_RESET_UARTC 49
+#define TEGRA186_RESET_UARTD 50
+#define TEGRA186_RESET_VI 51
+#define TEGRA186_RESET_VIC 52
+#define TEGRA186_RESET_XUSB_DEV 53
+#define TEGRA186_RESET_XUSB_HOST 54
+#define TEGRA186_RESET_XUSB_PADCTL 55
+#define TEGRA186_RESET_XUSB_SS 56
+#define TEGRA186_RESET_AON_APB 57
+#define TEGRA186_RESET_AXI_CBB 58
+#define TEGRA186_RESET_BPMP_APB 59
+#define TEGRA186_RESET_CAN1 60
+#define TEGRA186_RESET_CAN2 61
+#define TEGRA186_RESET_DMIC5 62
+#define TEGRA186_RESET_DSIC 63
+#define TEGRA186_RESET_DSID 64
+#define TEGRA186_RESET_EMC_EMC 65
+#define TEGRA186_RESET_EMC_MEM 66
+#define TEGRA186_RESET_EMCSB_EMC 67
+#define TEGRA186_RESET_EMCSB_MEM 68
+#define TEGRA186_RESET_EQOS 69
+#define TEGRA186_RESET_GPCDMA 70
+#define TEGRA186_RESET_GPIO_CTL0 71
+#define TEGRA186_RESET_GPIO_CTL1 72
+#define TEGRA186_RESET_GPIO_CTL2 73
+#define TEGRA186_RESET_GPIO_CTL3 74
+#define TEGRA186_RESET_GPIO_CTL4 75
+#define TEGRA186_RESET_GPIO_CTL5 76
+#define TEGRA186_RESET_I2C10 77
+#define TEGRA186_RESET_I2C12 78
+#define TEGRA186_RESET_I2C13 79
+#define TEGRA186_RESET_I2C14 80
+#define TEGRA186_RESET_I2C7 81
+#define TEGRA186_RESET_I2C8 82
+#define TEGRA186_RESET_I2C9 83
+#define TEGRA186_RESET_JTAG2AXI 84
+#define TEGRA186_RESET_MPHY_IOBIST 85
+#define TEGRA186_RESET_MPHY_L0_RX 86
+#define TEGRA186_RESET_MPHY_L0_TX 87
+#define TEGRA186_RESET_NVCSI 88
+#define TEGRA186_RESET_NVDISPLAY0_HEAD0 89
+#define TEGRA186_RESET_NVDISPLAY0_HEAD1 90
+#define TEGRA186_RESET_NVDISPLAY0_HEAD2 91
+#define TEGRA186_RESET_NVDISPLAY0_MISC 92
+#define TEGRA186_RESET_NVDISPLAY0_WGRP0 93
+#define TEGRA186_RESET_NVDISPLAY0_WGRP1 94
+#define TEGRA186_RESET_NVDISPLAY0_WGRP2 95
+#define TEGRA186_RESET_NVDISPLAY0_WGRP3 96
+#define TEGRA186_RESET_NVDISPLAY0_WGRP4 97
+#define TEGRA186_RESET_NVDISPLAY0_WGRP5 98
+#define TEGRA186_RESET_PWM1 99
+#define TEGRA186_RESET_PWM2 100
+#define TEGRA186_RESET_PWM3 101
+#define TEGRA186_RESET_PWM4 102
+#define TEGRA186_RESET_PWM5 103
+#define TEGRA186_RESET_PWM6 104
+#define TEGRA186_RESET_PWM7 105
+#define TEGRA186_RESET_PWM8 106
+#define TEGRA186_RESET_SCE_APB 107
+#define TEGRA186_RESET_SOR1 108
+#define TEGRA186_RESET_TACH 109
+#define TEGRA186_RESET_TSC 110
+#define TEGRA186_RESET_UARTF 111
+#define TEGRA186_RESET_UARTG 112
+#define TEGRA186_RESET_UFSHC 113
+#define TEGRA186_RESET_UFSHC_AXI_M 114
+#define TEGRA186_RESET_UPHY 115
+#define TEGRA186_RESET_ADSP 116
+#define TEGRA186_RESET_ADSPDBG 117
+#define TEGRA186_RESET_ADSPINTF 118
+#define TEGRA186_RESET_ADSPNEON 119
+#define TEGRA186_RESET_ADSPPERIPH 120
+#define TEGRA186_RESET_ADSPSCU 121
+#define TEGRA186_RESET_ADSPWDT 122
+#define TEGRA186_RESET_APE 123
+#define TEGRA186_RESET_DPAUX1 124
+#define TEGRA186_RESET_NVDEC 125
+#define TEGRA186_RESET_NVENC 126
+#define TEGRA186_RESET_NVJPG 127
+#define TEGRA186_RESET_PEX_USB_UPHY 128
+#define TEGRA186_RESET_QSPI 129
+#define TEGRA186_RESET_TSECB 130
+#define TEGRA186_RESET_VI_I2C 131
+#define TEGRA186_RESET_UARTE 132
+#define TEGRA186_RESET_TOP_GTE 133
+#define TEGRA186_RESET_SHSP 134
+#define TEGRA186_RESET_PEX_USB_UPHY_L5 135
+#define TEGRA186_RESET_PEX_USB_UPHY_L4 136
+#define TEGRA186_RESET_PEX_USB_UPHY_L3 137
+#define TEGRA186_RESET_PEX_USB_UPHY_L2 138
+#define TEGRA186_RESET_PEX_USB_UPHY_L1 139
+#define TEGRA186_RESET_PEX_USB_UPHY_L0 140
+#define TEGRA186_RESET_PEX_USB_UPHY_PLL1 141
+#define TEGRA186_RESET_PEX_USB_UPHY_PLL0 142
+#define TEGRA186_RESET_TSCTNVI 143
+#define TEGRA186_RESET_EXTPERIPH4 144
+#define TEGRA186_RESET_DSIPADCTL 145
+#define TEGRA186_RESET_AUD_MCLK 146
+#define TEGRA186_RESET_MPHY_CLK_CTL 147
+#define TEGRA186_RESET_MPHY_L1_RX 148
+#define TEGRA186_RESET_MPHY_L1_TX 149
+#define TEGRA186_RESET_UFSHC_LP 150
+#define TEGRA186_RESET_BPMP_NIC 151
+#define TEGRA186_RESET_BPMP_NSYSPORESET 152
+#define TEGRA186_RESET_BPMP_NRESET 153
+#define TEGRA186_RESET_BPMP_DBGRESETN 154
+#define TEGRA186_RESET_BPMP_PRESETDBGN 155
+#define TEGRA186_RESET_BPMP_PM 156
+#define TEGRA186_RESET_BPMP_CVC 157
+#define TEGRA186_RESET_BPMP_DMA 158
+#define TEGRA186_RESET_BPMP_HSP 159
+#define TEGRA186_RESET_TSCTNBPMP 160
+#define TEGRA186_RESET_BPMP_TKE 161
+#define TEGRA186_RESET_BPMP_GTE 162
+#define TEGRA186_RESET_BPMP_PM_ACTMON 163
+#define TEGRA186_RESET_AON_NIC 164
+#define TEGRA186_RESET_AON_NSYSPORESET 165
+#define TEGRA186_RESET_AON_NRESET 166
+#define TEGRA186_RESET_AON_DBGRESETN 167
+#define TEGRA186_RESET_AON_PRESETDBGN 168
+#define TEGRA186_RESET_AON_ACTMON 169
+#define TEGRA186_RESET_AOPM 170
+#define TEGRA186_RESET_AOVC 171
+#define TEGRA186_RESET_AON_DMA 172
+#define TEGRA186_RESET_AON_GPIO 173
+#define TEGRA186_RESET_AON_HSP 174
+#define TEGRA186_RESET_TSCTNAON 175
+#define TEGRA186_RESET_AON_TKE 176
+#define TEGRA186_RESET_AON_GTE 177
+#define TEGRA186_RESET_SCE_NIC 178
+#define TEGRA186_RESET_SCE_NSYSPORESET 179
+#define TEGRA186_RESET_SCE_NRESET 180
+#define TEGRA186_RESET_SCE_DBGRESETN 181
+#define TEGRA186_RESET_SCE_PRESETDBGN 182
+#define TEGRA186_RESET_SCE_ACTMON 183
+#define TEGRA186_RESET_SCE_PM 184
+#define TEGRA186_RESET_SCE_DMA 185
+#define TEGRA186_RESET_SCE_HSP 186
+#define TEGRA186_RESET_TSCTNSCE 187
+#define TEGRA186_RESET_SCE_TKE 188
+#define TEGRA186_RESET_SCE_GTE 189
+#define TEGRA186_RESET_SCE_CFG 190
+#define TEGRA186_RESET_ADSP_ALL 191
+/** @brief controls the power up/down sequence of UFSHC PSW partition. Controls LP_PWR_READY, LP_ISOL_EN, and LP_RESET_N signals */
+#define TEGRA186_RESET_UFSHC_LP_SEQ 192
+#define TEGRA186_RESET_SIZE 193
+
+#endif
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 43b28f04a1f5..5b36974ed60a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -56,6 +56,27 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
acpi_fwnode_handle(adev) : NULL)
#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
+static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
+{
+ struct fwnode_handle *fwnode;
+
+ fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL);
+ if (!fwnode)
+ return NULL;
+
+ fwnode->type = FWNODE_ACPI_STATIC;
+
+ return fwnode;
+}
+
+static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode)
+{
+ if (WARN_ON(!fwnode || fwnode->type != FWNODE_ACPI_STATIC))
+ return;
+
+ kfree(fwnode);
+}
+
/**
* ACPI_DEVICE_CLASS - macro used to describe an ACPI device with
* the PCI-defined class-code information
@@ -416,6 +437,8 @@ static inline int acpi_dev_filter_resource_type_cb(struct acpi_resource *ares,
return acpi_dev_filter_resource_type(ares, (unsigned long)arg);
}
+struct acpi_device *acpi_resource_consumer(struct resource *res);
+
int acpi_check_resource_conflict(const struct resource *res);
int acpi_check_region(resource_size_t start, resource_size_t n,
@@ -741,6 +764,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
return DEV_DMA_NOT_SUPPORTED;
}
+static inline void acpi_dma_configure(struct device *dev,
+ enum dev_dma_attr attr) { }
+
+static inline void acpi_dma_deconfigure(struct device *dev) { }
+
#define ACPI_PTR(_ptr) (NULL)
static inline void acpi_device_set_enumerated(struct acpi_device *adev)
@@ -761,6 +789,11 @@ static inline int acpi_reconfig_notifier_unregister(struct notifier_block *nb)
return -EINVAL;
}
+static inline struct acpi_device *acpi_resource_consumer(struct resource *res)
+{
+ return NULL;
+}
+
#endif /* !CONFIG_ACPI */
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 0e32dac8fd03..77e08099e554 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -23,20 +23,36 @@
#include <linux/fwnode.h>
#include <linux/irqdomain.h>
+#define IORT_IRQ_MASK(irq) (irq & 0xffffffffULL)
+#define IORT_IRQ_TRIGGER_MASK(irq) ((irq >> 32) & 0xffffffffULL)
+
int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
void iort_deregister_domain_token(int trans_id);
struct fwnode_handle *iort_find_domain_token(int trans_id);
#ifdef CONFIG_ACPI_IORT
void acpi_iort_init(void);
+bool iort_node_match(u8 type);
u32 iort_msi_map_rid(struct device *dev, u32 req_id);
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
+/* IOMMU interface */
+void iort_set_dma_mask(struct device *dev);
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
#else
static inline void acpi_iort_init(void) { }
+static inline bool iort_node_match(u8 type) { return false; }
static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
{ return req_id; }
static inline struct irq_domain *iort_get_device_domain(struct device *dev,
u32 req_id)
{ return NULL; }
+/* IOMMU interface */
+static inline void iort_set_dma_mask(struct device *dev) { }
+static inline
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{ return NULL; }
#endif
+#define IORT_ACPI_DECLARE(name, table_id, fn) \
+ ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
+
#endif /* __ACPI_IORT_H__ */
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 27e9ec8778eb..5308eae9ce35 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -84,6 +84,8 @@ struct pl08x_channel_data {
* running any DMA transfer and multiplexing can be recycled
* @lli_buses: buses which LLIs can be fetched from: PL08X_AHB1 | PL08X_AHB2
* @mem_buses: buses which memory can be accessed from: PL08X_AHB1 | PL08X_AHB2
+ * @slave_map: DMA slave matching table
+ * @slave_map_len: number of elements in @slave_map
*/
struct pl08x_platform_data {
struct pl08x_channel_data *slave_channels;
@@ -93,6 +95,8 @@ struct pl08x_platform_data {
void (*put_xfer_signal)(const struct pl08x_channel_data *, int);
u8 lli_buses;
u8 mem_buses;
+ const struct dma_slave_map *slave_map;
+ int slave_map_len;
};
#ifdef CONFIG_AMBA_PL08X
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 32c589062bd9..7f7e9a7e3839 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -61,6 +61,10 @@ void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir, unsigned long attrs);
void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir, unsigned long attrs);
+dma_addr_t iommu_dma_map_resource(struct device *dev, phys_addr_t phys,
+ size_t size, enum dma_data_direction dir, unsigned long attrs);
+void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir, unsigned long attrs);
int iommu_dma_supported(struct device *dev, u64 mask);
int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index cc535a478bae..feee6ec6a13b 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -336,6 +336,12 @@ enum dma_slave_buswidth {
* may or may not be applicable on memory sources.
* @dst_maxburst: same as src_maxburst but for destination target
* mutatis mutandis.
+ * @src_port_window_size: The length of the register area in words the data need
+ * to be accessed on the device side. It is only used for devices which is using
+ * an area instead of a single register to receive the data. Typically the DMA
+ * loops in this area in order to transfer the data.
+ * @dst_port_window_size: same as src_port_window_size but for the destination
+ * port.
* @device_fc: Flow Controller Settings. Only valid for slave channels. Fill
* with 'true' if peripheral should be flow controller. Direction will be
* selected at Runtime.
@@ -363,6 +369,8 @@ struct dma_slave_config {
enum dma_slave_buswidth dst_addr_width;
u32 src_maxburst;
u32 dst_maxburst;
+ u32 src_port_window_size;
+ u32 dst_port_window_size;
bool device_fc;
unsigned int slave_id;
};
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index d4a884db16a3..3633e8beff39 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -947,6 +947,10 @@ extern int __disable_trace_on_warning;
#define INIT_TRACE_RECURSION .trace_recursion = 0,
#endif
+int tracepoint_printk_sysctl(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos);
+
#else /* CONFIG_TRACING */
static inline void disable_trace_on_warning(void) { }
#endif /* CONFIG_TRACING */
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 851671742790..8bd28ce6d76e 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -17,8 +17,9 @@ enum fwnode_type {
FWNODE_OF,
FWNODE_ACPI,
FWNODE_ACPI_DATA,
+ FWNODE_ACPI_STATIC,
FWNODE_PDATA,
- FWNODE_IRQCHIP,
+ FWNODE_IRQCHIP
};
struct fwnode_handle {
diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h
index c2e3324f9468..a1385023a29b 100644
--- a/include/linux/i2c-smbus.h
+++ b/include/linux/i2c-smbus.h
@@ -50,31 +50,4 @@ struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter,
struct i2c_smbus_alert_setup *setup);
int i2c_handle_smbus_alert(struct i2c_client *ara);
-/**
- * smbus_host_notify - internal structure used by the Host Notify mechanism.
- * @adapter: the I2C adapter associated with this struct
- * @work: worker used to schedule the IRQ in the slave device
- * @lock: spinlock to check if a notification is already pending
- * @pending: flag set when a notification is pending (any new notification will
- * be rejected if pending is true)
- * @payload: the actual payload of the Host Notify event
- * @addr: the address of the slave device which raised the notification
- *
- * This struct needs to be allocated by i2c_setup_smbus_host_notify() and does
- * not need to be freed. Internally, i2c_setup_smbus_host_notify() uses a
- * managed resource to clean this up when the adapter get released.
- */
-struct smbus_host_notify {
- struct i2c_adapter *adapter;
- struct work_struct work;
- spinlock_t lock;
- bool pending;
- u16 payload;
- u8 addr;
-};
-
-struct smbus_host_notify *i2c_setup_smbus_host_notify(struct i2c_adapter *adap);
-int i2c_handle_smbus_host_notify(struct smbus_host_notify *host_notify,
- unsigned short addr, unsigned int data);
-
#endif /* _LINUX_I2C_SMBUS_H */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 6422eef428c4..b2109c522dec 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -30,6 +30,7 @@
#include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */
#include <linux/mutex.h>
+#include <linux/irqdomain.h> /* for Host Notify IRQ */
#include <linux/of.h> /* for struct device_node */
#include <linux/swab.h> /* for swab16 */
#include <uapi/linux/i2c.h>
@@ -135,7 +136,8 @@ enum i2c_alert_protocol {
* struct i2c_driver - represent an I2C device driver
* @class: What kind of i2c device we instantiate (for detect)
* @attach_adapter: Callback for bus addition (deprecated)
- * @probe: Callback for device binding
+ * @probe: Callback for device binding - soon to be deprecated
+ * @probe_new: New callback for device binding
* @remove: Callback for device unbinding
* @shutdown: Callback for device shutdown
* @alert: Alert callback, for example for the SMBus alert protocol
@@ -178,6 +180,11 @@ struct i2c_driver {
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
+ /* New driver model interface to aid the seamless removal of the
+ * current probe()'s, more commonly unused than used second parameter.
+ */
+ int (*probe_new)(struct i2c_client *);
+
/* driver model interfaces that don't relate to enumeration */
void (*shutdown)(struct i2c_client *);
@@ -243,6 +250,8 @@ struct i2c_client {
extern struct i2c_client *i2c_verify_client(struct device *dev);
extern struct i2c_adapter *i2c_verify_adapter(struct device *dev);
+extern const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+ const struct i2c_client *client);
static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
{
@@ -567,6 +576,8 @@ struct i2c_adapter {
struct i2c_bus_recovery_info *bus_recovery_info;
const struct i2c_adapter_quirks *quirks;
+
+ struct irq_domain *host_notify_domain;
};
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
@@ -739,6 +750,7 @@ static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
}
+int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
/**
* module_i2c_driver() - Helper macro for registering a modular I2C driver
* @__i2c_driver: i2c_driver struct
@@ -774,6 +786,10 @@ extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
/* must call i2c_put_adapter() when done with returned i2c_adapter device */
struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node);
+extern const struct of_device_id
+*i2c_of_match_device(const struct of_device_id *matches,
+ struct i2c_client *client);
+
#else
static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
@@ -790,6 +806,14 @@ static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node
{
return NULL;
}
+
+static inline const struct of_device_id
+*i2c_of_match_device(const struct of_device_id *matches,
+ struct i2c_client *client)
+{
+ return NULL;
+}
+
#endif /* CONFIG_OF */
#if IS_ENABLED(CONFIG_ACPI)
diff --git a/include/linux/i2c/mlxcpld.h b/include/linux/i2c/mlxcpld.h
new file mode 100644
index 000000000000..b08dcb183fca
--- /dev/null
+++ b/include/linux/i2c/mlxcpld.h
@@ -0,0 +1,52 @@
+/*
+ * mlxcpld.h - Mellanox I2C multiplexer support in CPLD
+ *
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Michael Shych <michaels@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_I2C_MLXCPLD_H
+#define _LINUX_I2C_MLXCPLD_H
+
+/* Platform data for the CPLD I2C multiplexers */
+
+/* mlxcpld_mux_plat_data - per mux data, used with i2c_register_board_info
+ * @adap_ids - adapter array
+ * @num_adaps - number of adapters
+ * @sel_reg_addr - mux select register offset in CPLD space
+ */
+struct mlxcpld_mux_plat_data {
+ int *adap_ids;
+ int num_adaps;
+ int sel_reg_addr;
+};
+
+#endif /* _LINUX_I2C_MLXCPLD_H */
diff --git a/include/linux/init.h b/include/linux/init.h
index e30104ceb86d..885c3e6d0f9d 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -126,6 +126,9 @@ void prepare_namespace(void);
void __init load_default_modules(void);
int __init init_rootfs(void);
+#if defined(CONFIG_DEBUG_RODATA) || defined(CONFIG_DEBUG_SET_MODULE_RONX)
+extern bool rodata_enabled;
+#endif
#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void);
#endif
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index f185156de74d..a4c94b86401e 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -50,6 +50,7 @@ struct iomap {
#define IOMAP_ZERO (1 << 1) /* zeroing operation, may skip holes */
#define IOMAP_REPORT (1 << 2) /* report extent status, e.g. FIEMAP */
#define IOMAP_FAULT (1 << 3) /* mapping for page fault */
+#define IOMAP_DIRECT (1 << 4) /* direct I/O */
struct iomap_ops {
/*
@@ -83,4 +84,14 @@ int iomap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
loff_t start, loff_t len, struct iomap_ops *ops);
+/*
+ * Flags for direct I/O ->end_io:
+ */
+#define IOMAP_DIO_UNWRITTEN (1 << 0) /* covers unwritten extent(s) */
+#define IOMAP_DIO_COW (1 << 1) /* covers COW extent(s) */
+typedef int (iomap_dio_end_io_t)(struct kiocb *iocb, ssize_t ret,
+ unsigned flags);
+ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
+ struct iomap_ops *ops, iomap_dio_end_io_t end_io);
+
#endif /* LINUX_IOMAP_H */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 436dc21318af..0ff5111f6959 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -253,6 +253,7 @@ extern void iommu_group_remove_device(struct device *dev);
extern int iommu_group_for_each_dev(struct iommu_group *group, void *data,
int (*fn)(struct device *, void *));
extern struct iommu_group *iommu_group_get(struct device *dev);
+extern struct iommu_group *iommu_group_ref_get(struct iommu_group *group);
extern void iommu_group_put(struct iommu_group *group);
extern int iommu_group_register_notifier(struct iommu_group *group,
struct notifier_block *nb);
@@ -351,6 +352,9 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
const struct iommu_ops *ops);
void iommu_fwspec_free(struct device *dev);
int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
+void iommu_register_instance(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops);
+const struct iommu_ops *iommu_get_instance(struct fwnode_handle *fwnode);
#else /* CONFIG_IOMMU_API */
@@ -580,6 +584,17 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
return -ENODEV;
}
+static inline void iommu_register_instance(struct fwnode_handle *fwnode,
+ const struct iommu_ops *ops)
+{
+}
+
+static inline
+const struct iommu_ops *iommu_get_instance(struct fwnode_handle *fwnode)
+{
+ return NULL;
+}
+
#endif /* CONFIG_IOMMU_API */
#endif /* __LINUX_IOMMU_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index d234cd31e75a..56aec84237ad 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -511,6 +511,15 @@ extern enum system_states {
#define TAINT_UNSIGNED_MODULE 13
#define TAINT_SOFTLOCKUP 14
#define TAINT_LIVEPATCH 15
+#define TAINT_FLAGS_COUNT 16
+
+struct taint_flag {
+ char true; /* character printed when tainted */
+ char false; /* character printed when not tainted */
+ bool module; /* also show as a per-module taint flag */
+};
+
+extern const struct taint_flag taint_flags[TAINT_FLAGS_COUNT];
extern const char hex_asc[];
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index c1458fede1f9..1e327bb80838 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -338,9 +338,18 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
extern void lock_release(struct lockdep_map *lock, int nested,
unsigned long ip);
-#define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map)
+/*
+ * Same "read" as for lock_acquire(), except -1 means any.
+ */
+extern int lock_is_held_type(struct lockdep_map *lock, int read);
+
+static inline int lock_is_held(struct lockdep_map *lock)
+{
+ return lock_is_held_type(lock, -1);
+}
-extern int lock_is_held(struct lockdep_map *lock);
+#define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map)
+#define lockdep_is_held_type(lock, r) lock_is_held_type(&(lock)->dep_map, (r))
extern void lock_set_class(struct lockdep_map *lock, const char *name,
struct lock_class_key *key, unsigned int subclass,
@@ -372,6 +381,14 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
WARN_ON(debug_locks && !lockdep_is_held(l)); \
} while (0)
+#define lockdep_assert_held_exclusive(l) do { \
+ WARN_ON(debug_locks && !lockdep_is_held_type(l, 0)); \
+ } while (0)
+
+#define lockdep_assert_held_read(l) do { \
+ WARN_ON(debug_locks && !lockdep_is_held_type(l, 1)); \
+ } while (0)
+
#define lockdep_assert_held_once(l) do { \
WARN_ON_ONCE(debug_locks && !lockdep_is_held(l)); \
} while (0)
@@ -428,7 +445,11 @@ struct lock_class_key { };
#define lockdep_depth(tsk) (0)
+#define lockdep_is_held_type(l, r) (1)
+
#define lockdep_assert_held(l) do { (void)(l); } while (0)
+#define lockdep_assert_held_exclusive(l) do { (void)(l); } while (0)
+#define lockdep_assert_held_read(l) do { (void)(l); } while (0)
#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
#define lockdep_recursing(tsk) (0)
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
index 4ccda8969639..3cbec4b2496a 100644
--- a/include/linux/mfd/tps65217.h
+++ b/include/linux/mfd/tps65217.h
@@ -234,12 +234,11 @@ struct tps65217_bl_pdata {
int dft_brightness;
};
-enum tps65217_irq_type {
- TPS65217_IRQ_PB,
- TPS65217_IRQ_AC,
- TPS65217_IRQ_USB,
- TPS65217_NUM_IRQ
-};
+/* Interrupt numbers */
+#define TPS65217_IRQ_USB 0
+#define TPS65217_IRQ_AC 1
+#define TPS65217_IRQ_PB 2
+#define TPS65217_NUM_IRQ 3
/**
* struct tps65217_board - packages regulator init data
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index a5f0fbedf1e7..57bec544e20a 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -577,7 +577,7 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
u8 self_lb_en_modifiable[0x1];
u8 reserved_at_9[0x2];
u8 max_lso_cap[0x5];
- u8 reserved_at_10[0x2];
+ u8 multi_pkt_send_wqe[0x2];
u8 wqe_inline_mode[0x2];
u8 rss_ind_tbl_cap[0x4];
u8 reg_umr_sq[0x1];
diff --git a/include/linux/module.h b/include/linux/module.h
index 0c3207d26ac0..7c84273d60b9 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -399,7 +399,7 @@ struct module {
/* Arch-specific module values */
struct mod_arch_specific arch;
- unsigned int taints; /* same bits as kernel:tainted */
+ unsigned long taints; /* same bits as kernel:taint_flags */
#ifdef CONFIG_GENERIC_BUG
/* Support for BUG */
@@ -412,7 +412,7 @@ struct module {
/* Protected by RCU and/or module_mutex: use rcu_dereference() */
struct mod_kallsyms *kallsyms;
struct mod_kallsyms core_kallsyms;
-
+
/* Section attributes */
struct module_sect_attrs *sect_attrs;
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index e80b9c762a03..6a7fc5051099 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -31,8 +31,16 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
#endif /* CONFIG_OF_IOMMU */
-void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
-const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
+static inline void of_iommu_set_ops(struct device_node *np,
+ const struct iommu_ops *ops)
+{
+ iommu_register_instance(&np->fwnode, ops);
+}
+
+static inline const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
+{
+ return iommu_get_instance(&np->fwnode);
+}
extern struct of_device_id __iommu_of_table;
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 7fd5cfce9140..0e0974eceb80 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,6 +16,7 @@ int of_pci_get_devfn(struct device_node *np);
int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
int of_get_pci_domain_nr(struct device_node *node);
+int of_pci_get_max_link_speed(struct device_node *node);
void of_pci_check_probe_only(void);
int of_pci_map_rid(struct device_node *np, u32 rid,
const char *map_name, const char *map_mask_name,
@@ -62,6 +63,12 @@ static inline int of_pci_map_rid(struct device_node *np, u32 rid,
return -EINVAL;
}
+static inline int
+of_pci_get_max_link_speed(struct device_node *node)
+{
+ return -EINVAL;
+}
+
static inline void of_pci_check_probe_only(void) { }
#endif
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 7d63a66e8ed4..7a4e83a8c89c 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -24,7 +24,9 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
}
extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
-extern phys_addr_t pci_mcfg_lookup(u16 domain, struct resource *bus_res);
+struct pci_ecam_ops;
+extern int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
+ struct pci_ecam_ops **ecam_ops);
static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
{
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index 7adad206b1f4..f0d2b9451270 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -59,6 +59,15 @@ void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn,
/* default ECAM ops */
extern struct pci_ecam_ops pci_generic_ecam_ops;
+#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
+extern struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */
+extern struct pci_ecam_ops hisi_pcie_ops; /* HiSilicon */
+extern struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 1.x & 2.x */
+extern struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */
+extern struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */
+extern struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
+#endif
+
#ifdef CONFIG_PCI_HOST_GENERIC
/* for DT-based PCI controllers that support ECAM */
int pci_host_common_probe(struct platform_device *pdev,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 30d6c162e053..e2d1a124216a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -420,9 +420,13 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
struct pci_host_bridge {
struct device dev;
struct pci_bus *bus; /* root bus */
+ struct pci_ops *ops;
+ void *sysdata;
+ int busnr;
struct list_head windows; /* resource_entry */
void (*release_fn)(struct pci_host_bridge *);
void *release_data;
+ struct msi_controller *msi;
unsigned int ignore_reset_delay:1; /* for entire hierarchy */
/* Resource alignment requirements */
resource_size_t (*align_resource)(struct pci_dev *dev,
@@ -430,10 +434,23 @@ struct pci_host_bridge {
resource_size_t start,
resource_size_t size,
resource_size_t align);
+ unsigned long private[0] ____cacheline_aligned;
};
#define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
+static inline void *pci_host_bridge_priv(struct pci_host_bridge *bridge)
+{
+ return (void *)bridge->private;
+}
+
+static inline struct pci_host_bridge *pci_host_bridge_from_priv(void *priv)
+{
+ return container_of(priv, struct pci_host_bridge, private);
+}
+
+struct pci_host_bridge *pci_alloc_host_bridge(size_t priv);
+int pci_register_host_bridge(struct pci_host_bridge *bridge);
struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 8c7895061121..2e855afa0212 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -176,6 +176,7 @@ struct hotplug_params {
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp);
+bool pciehp_is_native(struct pci_dev *pdev);
int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags);
int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
int acpi_pci_detect_ejectable(acpi_handle handle);
@@ -185,5 +186,6 @@ static inline int pci_get_hp_params(struct pci_dev *dev,
{
return -ENODEV;
}
+static inline bool pciehp_is_native(struct pci_dev *pdev) { return true; }
#endif
#endif
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index a5e6c7bca610..73dda0edcb97 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2253,17 +2253,35 @@
#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000
#define PCI_VENDOR_ID_VMWARE 0x15ad
+#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07b0
#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0
#define PCI_VENDOR_ID_MELLANOX 0x15b3
-#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX3 0x1003
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO 0x1007
+#define PCI_DEVICE_ID_MELLANOX_CONNECTIB 0x1011
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX4 0x1013
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX 0x1015
+#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46
-#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
-#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
-#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
-#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
+#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
+#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
+#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
+#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
+#define PCI_DEVICE_ID_MELLANOX_HERMON_SDR 0x6340
+#define PCI_DEVICE_ID_MELLANOX_HERMON_DDR 0x634a
+#define PCI_DEVICE_ID_MELLANOX_HERMON_QDR 0x6354
+#define PCI_DEVICE_ID_MELLANOX_HERMON_EN 0x6368
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN 0x6372
+#define PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2 0x6732
+#define PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2 0x673c
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2 0x6746
+#define PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2 0x6750
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2 0x675a
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2 0x6764
+#define PCI_DEVICE_ID_MELLANOX_CONNECTX2 0x676e
#define PCI_VENDOR_ID_DFI 0x15bd
diff --git a/include/linux/platform_data/dma-dw.h b/include/linux/platform_data/dma-dw.h
index 5f0e11e7354c..e69e415d0d98 100644
--- a/include/linux/platform_data/dma-dw.h
+++ b/include/linux/platform_data/dma-dw.h
@@ -14,6 +14,7 @@
#include <linux/device.h>
#define DW_DMA_MAX_NR_MASTERS 4
+#define DW_DMA_MAX_NR_CHANNELS 8
/**
* struct dw_dma_slave - Controller-specific information about a slave
@@ -40,19 +41,18 @@ struct dw_dma_slave {
* @is_private: The device channels should be marked as private and not for
* by the general purpose DMA channel allocator.
* @is_memcpy: The device channels do support memory-to-memory transfers.
- * @is_nollp: The device channels does not support multi block transfers.
* @chan_allocation_order: Allocate channels starting from 0 or 7
* @chan_priority: Set channel priority increasing from 0 to 7 or 7 to 0.
* @block_size: Maximum block size supported by the controller
* @nr_masters: Number of AHB masters supported by the controller
* @data_width: Maximum data width supported by hardware per AHB master
* (in bytes, power of 2)
+ * @multi_block: Multi block transfers supported by hardware per channel.
*/
struct dw_dma_platform_data {
unsigned int nr_channels;
bool is_private;
bool is_memcpy;
- bool is_nollp;
#define CHAN_ALLOCATION_ASCENDING 0 /* zero to seven */
#define CHAN_ALLOCATION_DESCENDING 1 /* seven to zero */
unsigned char chan_allocation_order;
@@ -62,6 +62,7 @@ struct dw_dma_platform_data {
unsigned int block_size;
unsigned char nr_masters;
unsigned char data_width[DW_DMA_MAX_NR_MASTERS];
+ unsigned char multi_block[DW_DMA_MAX_NR_CHANNELS];
};
#endif /* _PLATFORM_DATA_DMA_DW_H */
diff --git a/include/linux/platform_data/mlxcpld-hotplug.h b/include/linux/platform_data/mlxcpld-hotplug.h
new file mode 100644
index 000000000000..e4cfcffaa6f4
--- /dev/null
+++ b/include/linux/platform_data/mlxcpld-hotplug.h
@@ -0,0 +1,99 @@
+/*
+ * include/linux/platform_data/mlxcpld-hotplug.h
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H
+#define __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H
+
+/**
+ * struct mlxcpld_hotplug_device - I2C device data:
+ * @adapter: I2C device adapter;
+ * @client: I2C device client;
+ * @brdinfo: device board information;
+ * @bus: I2C bus, where device is attached;
+ *
+ * Structure represents I2C hotplug device static data (board topology) and
+ * dynamic data (related kernel objects handles).
+ */
+struct mlxcpld_hotplug_device {
+ struct i2c_adapter *adapter;
+ struct i2c_client *client;
+ struct i2c_board_info brdinfo;
+ u16 bus;
+};
+
+/**
+ * struct mlxcpld_hotplug_platform_data - device platform data:
+ * @top_aggr_offset: offset of top aggregation interrupt register;
+ * @top_aggr_mask: top aggregation interrupt common mask;
+ * @top_aggr_psu_mask: top aggregation interrupt PSU mask;
+ * @psu_reg_offset: offset of PSU interrupt register;
+ * @psu_mask: PSU interrupt mask;
+ * @psu_count: number of equipped replaceable PSUs;
+ * @psu: pointer to PSU devices data array;
+ * @top_aggr_pwr_mask: top aggregation interrupt power mask;
+ * @pwr_reg_offset: offset of power interrupt register
+ * @pwr_mask: power interrupt mask;
+ * @pwr_count: number of power sources;
+ * @pwr: pointer to power devices data array;
+ * @top_aggr_fan_mask: top aggregation interrupt FAN mask;
+ * @fan_reg_offset: offset of FAN interrupt register;
+ * @fan_mask: FAN interrupt mask;
+ * @fan_count: number of equipped replaceable FANs;
+ * @fan: pointer to FAN devices data array;
+ *
+ * Structure represents board platform data, related to system hotplug events,
+ * like FAN, PSU, power cable insertion and removing. This data provides the
+ * number of hot-pluggable devices and hardware description for event handling.
+ */
+struct mlxcpld_hotplug_platform_data {
+ u16 top_aggr_offset;
+ u8 top_aggr_mask;
+ u8 top_aggr_psu_mask;
+ u16 psu_reg_offset;
+ u8 psu_mask;
+ u8 psu_count;
+ struct mlxcpld_hotplug_device *psu;
+ u8 top_aggr_pwr_mask;
+ u16 pwr_reg_offset;
+ u8 pwr_mask;
+ u8 pwr_count;
+ struct mlxcpld_hotplug_device *pwr;
+ u8 top_aggr_fan_mask;
+ u16 fan_reg_offset;
+ u8 fan_mask;
+ u8 fan_count;
+ struct mlxcpld_hotplug_device *fan;
+};
+
+#endif /* __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H */
diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h
index 5c1e21c87270..da79774078a7 100644
--- a/include/linux/platform_data/spi-s3c64xx.h
+++ b/include/linux/platform_data/spi-s3c64xx.h
@@ -40,9 +40,6 @@ struct s3c64xx_spi_info {
int num_cs;
bool no_cs;
int (*cfg_gpio)(void);
- dma_filter_fn filter;
- void *dma_tx;
- void *dma_rx;
};
/**
diff --git a/include/linux/platform_data/usb-davinci.h b/include/linux/platform_data/usb-davinci.h
index e0bc4abe69c2..0926e99f2e8f 100644
--- a/include/linux/platform_data/usb-davinci.h
+++ b/include/linux/platform_data/usb-davinci.h
@@ -11,29 +11,6 @@
#ifndef __ASM_ARCH_USB_H
#define __ASM_ARCH_USB_H
-/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */
-#define CFGCHIP2_PHYCLKGD (1 << 17)
-#define CFGCHIP2_VBUSSENSE (1 << 16)
-#define CFGCHIP2_RESET (1 << 15)
-#define CFGCHIP2_OTGMODE (3 << 13)
-#define CFGCHIP2_NO_OVERRIDE (0 << 13)
-#define CFGCHIP2_FORCE_HOST (1 << 13)
-#define CFGCHIP2_FORCE_DEVICE (2 << 13)
-#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13)
-#define CFGCHIP2_USB1PHYCLKMUX (1 << 12)
-#define CFGCHIP2_USB2PHYCLKMUX (1 << 11)
-#define CFGCHIP2_PHYPWRDN (1 << 10)
-#define CFGCHIP2_OTGPWRDN (1 << 9)
-#define CFGCHIP2_DATPOL (1 << 8)
-#define CFGCHIP2_USB1SUSPENDM (1 << 7)
-#define CFGCHIP2_PHY_PLLON (1 << 6) /* override PLL suspend */
-#define CFGCHIP2_SESENDEN (1 << 5) /* Vsess_end comparator */
-#define CFGCHIP2_VBDTCTEN (1 << 4) /* Vbus comparator */
-#define CFGCHIP2_REFFREQ (0xf << 0)
-#define CFGCHIP2_REFFREQ_12MHZ (1 << 0)
-#define CFGCHIP2_REFFREQ_24MHZ (2 << 0)
-#define CFGCHIP2_REFFREQ_48MHZ (3 << 0)
-
struct da8xx_ohci_root_hub;
typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
diff --git a/include/linux/soc/qcom/wcnss_ctrl.h b/include/linux/soc/qcom/wcnss_ctrl.h
index a37bc5538f19..eab64976a73b 100644
--- a/include/linux/soc/qcom/wcnss_ctrl.h
+++ b/include/linux/soc/qcom/wcnss_ctrl.h
@@ -3,6 +3,19 @@
#include <linux/soc/qcom/smd.h>
+#if IS_ENABLED(CONFIG_QCOM_WCNSS_CTRL)
+
struct qcom_smd_channel *qcom_wcnss_open_channel(void *wcnss, const char *name, qcom_smd_cb_t cb);
+#else
+
+static inline struct qcom_smd_channel*
+qcom_wcnss_open_channel(void *wcnss, const char *name, qcom_smd_cb_t cb)
+{
+ WARN_ON(1);
+ return ERR_PTR(-ENXIO);
+}
+
+#endif
+
#endif
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
new file mode 100644
index 000000000000..0ccbc138c26a
--- /dev/null
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -0,0 +1,249 @@
+/*
+ * Texas Instruments System Control Interface Protocol
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * 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 "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 __TISCI_PROTOCOL_H
+#define __TISCI_PROTOCOL_H
+
+/**
+ * struct ti_sci_version_info - version information structure
+ * @abi_major: Major ABI version. Change here implies risk of backward
+ * compatibility break.
+ * @abi_minor: Minor ABI version. Change here implies new feature addition,
+ * or compatible change in ABI.
+ * @firmware_revision: Firmware revision (not usually used).
+ * @firmware_description: Firmware description (not usually used).
+ */
+struct ti_sci_version_info {
+ u8 abi_major;
+ u8 abi_minor;
+ u16 firmware_revision;
+ char firmware_description[32];
+};
+
+struct ti_sci_handle;
+
+/**
+ * struct ti_sci_core_ops - SoC Core Operations
+ * @reboot_device: Reboot the SoC
+ * Returns 0 for successful request(ideally should never return),
+ * else returns corresponding error value.
+ */
+struct ti_sci_core_ops {
+ int (*reboot_device)(const struct ti_sci_handle *handle);
+};
+
+/**
+ * struct ti_sci_dev_ops - Device control operations
+ * @get_device: Command to request for device managed by TISCI
+ * Returns 0 for successful exclusive request, else returns
+ * corresponding error message.
+ * @idle_device: Command to idle a device managed by TISCI
+ * Returns 0 for successful exclusive request, else returns
+ * corresponding error message.
+ * @put_device: Command to release a device managed by TISCI
+ * Returns 0 for successful release, else returns corresponding
+ * error message.
+ * @is_valid: Check if the device ID is a valid ID.
+ * Returns 0 if the ID is valid, else returns corresponding error.
+ * @get_context_loss_count: Command to retrieve context loss counter - this
+ * increments every time the device looses context. Overflow
+ * is possible.
+ * - count: pointer to u32 which will retrieve counter
+ * Returns 0 for successful information request and count has
+ * proper data, else returns corresponding error message.
+ * @is_idle: Reports back about device idle state
+ * - req_state: Returns requested idle state
+ * Returns 0 for successful information request and req_state and
+ * current_state has proper data, else returns corresponding error
+ * message.
+ * @is_stop: Reports back about device stop state
+ * - req_state: Returns requested stop state
+ * - current_state: Returns current stop state
+ * Returns 0 for successful information request and req_state and
+ * current_state has proper data, else returns corresponding error
+ * message.
+ * @is_on: Reports back about device ON(or active) state
+ * - req_state: Returns requested ON state
+ * - current_state: Returns current ON state
+ * Returns 0 for successful information request and req_state and
+ * current_state has proper data, else returns corresponding error
+ * message.
+ * @is_transitioning: Reports back if the device is in the middle of transition
+ * of state.
+ * -current_state: Returns 'true' if currently transitioning.
+ * @set_device_resets: Command to configure resets for device managed by TISCI.
+ * -reset_state: Device specific reset bit field
+ * Returns 0 for successful request, else returns
+ * corresponding error message.
+ * @get_device_resets: Command to read state of resets for device managed
+ * by TISCI.
+ * -reset_state: pointer to u32 which will retrieve resets
+ * Returns 0 for successful request, else returns
+ * corresponding error message.
+ *
+ * NOTE: for all these functions, the following parameters are generic in
+ * nature:
+ * -handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * -id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ */
+struct ti_sci_dev_ops {
+ int (*get_device)(const struct ti_sci_handle *handle, u32 id);
+ int (*idle_device)(const struct ti_sci_handle *handle, u32 id);
+ int (*put_device)(const struct ti_sci_handle *handle, u32 id);
+ int (*is_valid)(const struct ti_sci_handle *handle, u32 id);
+ int (*get_context_loss_count)(const struct ti_sci_handle *handle,
+ u32 id, u32 *count);
+ int (*is_idle)(const struct ti_sci_handle *handle, u32 id,
+ bool *requested_state);
+ int (*is_stop)(const struct ti_sci_handle *handle, u32 id,
+ bool *req_state, bool *current_state);
+ int (*is_on)(const struct ti_sci_handle *handle, u32 id,
+ bool *req_state, bool *current_state);
+ int (*is_transitioning)(const struct ti_sci_handle *handle, u32 id,
+ bool *current_state);
+ int (*set_device_resets)(const struct ti_sci_handle *handle, u32 id,
+ u32 reset_state);
+ int (*get_device_resets)(const struct ti_sci_handle *handle, u32 id,
+ u32 *reset_state);
+};
+
+/**
+ * struct ti_sci_clk_ops - Clock control operations
+ * @get_clock: Request for activation of clock and manage by processor
+ * - needs_ssc: 'true' if Spread Spectrum clock is desired.
+ * - can_change_freq: 'true' if frequency change is desired.
+ * - enable_input_term: 'true' if input termination is desired.
+ * @idle_clock: Request for Idling a clock managed by processor
+ * @put_clock: Release the clock to be auto managed by TISCI
+ * @is_auto: Is the clock being auto managed
+ * - req_state: state indicating if the clock is auto managed
+ * @is_on: Is the clock ON
+ * - req_state: if the clock is requested to be forced ON
+ * - current_state: if the clock is currently ON
+ * @is_off: Is the clock OFF
+ * - req_state: if the clock is requested to be forced OFF
+ * - current_state: if the clock is currently Gated
+ * @set_parent: Set the clock source of a specific device clock
+ * - parent_id: Parent clock identifier to set.
+ * @get_parent: Get the current clock source of a specific device clock
+ * - parent_id: Parent clock identifier which is the parent.
+ * @get_num_parents: Get the number of parents of the current clock source
+ * - num_parents: returns the number of parent clocks.
+ * @get_best_match_freq: Find a best matching frequency for a frequency
+ * range.
+ * - match_freq: Best matching frequency in Hz.
+ * @set_freq: Set the Clock frequency
+ * @get_freq: Get the Clock frequency
+ * - current_freq: Frequency in Hz that the clock is at.
+ *
+ * NOTE: for all these functions, the following parameters are generic in
+ * nature:
+ * -handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * -did: Device identifier this request is for
+ * -cid: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * -min_freq: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * -target_freq: The target clock frequency in Hz. A frequency will be
+ * processed as close to this target frequency as possible.
+ * -max_freq: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ *
+ * Request for the clock - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_clock with put_clock. No refcounting is
+ * managed by driver for that purpose.
+ */
+struct ti_sci_clk_ops {
+ int (*get_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ bool needs_ssc, bool can_change_freq,
+ bool enable_input_term);
+ int (*idle_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid);
+ int (*put_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid);
+ int (*is_auto)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ bool *req_state);
+ int (*is_on)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ bool *req_state, bool *current_state);
+ int (*is_off)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ bool *req_state, bool *current_state);
+ int (*set_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ u8 parent_id);
+ int (*get_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ u8 *parent_id);
+ int (*get_num_parents)(const struct ti_sci_handle *handle, u32 did,
+ u8 cid, u8 *num_parents);
+ int (*get_best_match_freq)(const struct ti_sci_handle *handle, u32 did,
+ u8 cid, u64 min_freq, u64 target_freq,
+ u64 max_freq, u64 *match_freq);
+ int (*set_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ u64 min_freq, u64 target_freq, u64 max_freq);
+ int (*get_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ u64 *current_freq);
+};
+
+/**
+ * struct ti_sci_ops - Function support for TI SCI
+ * @dev_ops: Device specific operations
+ * @clk_ops: Clock specific operations
+ */
+struct ti_sci_ops {
+ struct ti_sci_core_ops core_ops;
+ struct ti_sci_dev_ops dev_ops;
+ struct ti_sci_clk_ops clk_ops;
+};
+
+/**
+ * struct ti_sci_handle - Handle returned to TI SCI clients for usage.
+ * @version: structure containing version information
+ * @ops: operations that are made available to TI SCI clients
+ */
+struct ti_sci_handle {
+ struct ti_sci_version_info version;
+ struct ti_sci_ops ops;
+};
+
+#if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL)
+const struct ti_sci_handle *ti_sci_get_handle(struct device *dev);
+int ti_sci_put_handle(const struct ti_sci_handle *handle);
+const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev);
+
+#else /* CONFIG_TI_SCI_PROTOCOL */
+
+static inline const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+static inline int ti_sci_put_handle(const struct ti_sci_handle *handle)
+{
+ return -EINVAL;
+}
+
+static inline
+const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+#endif /* CONFIG_TI_SCI_PROTOCOL */
+
+#endif /* __TISCI_PROTOCOL_H */
diff --git a/include/linux/stm.h b/include/linux/stm.h
index 8369d8a8cabd..210ff2292361 100644
--- a/include/linux/stm.h
+++ b/include/linux/stm.h
@@ -133,7 +133,7 @@ int stm_source_register_device(struct device *parent,
struct stm_source_data *data);
void stm_source_unregister_device(struct stm_source_data *data);
-int stm_source_write(struct stm_source_data *data, unsigned int chan,
- const char *buf, size_t count);
+int notrace stm_source_write(struct stm_source_data *data, unsigned int chan,
+ const char *buf, size_t count);
#endif /* _STM_H_ */
diff --git a/include/linux/trace.h b/include/linux/trace.h
new file mode 100644
index 000000000000..9330a58e2651
--- /dev/null
+++ b/include/linux/trace.h
@@ -0,0 +1,28 @@
+#ifndef _LINUX_TRACE_H
+#define _LINUX_TRACE_H
+
+#ifdef CONFIG_TRACING
+/*
+ * The trace export - an export of Ftrace output. The trace_export
+ * can process traces and export them to a registered destination as
+ * an addition to the current only output of Ftrace - i.e. ring buffer.
+ *
+ * If you want traces to be sent to some other place rather than ring
+ * buffer only, just need to register a new trace_export and implement
+ * its own .write() function for writing traces to the storage.
+ *
+ * next - pointer to the next trace_export
+ * write - copy traces which have been delt with ->commit() to
+ * the destination
+ */
+struct trace_export {
+ struct trace_export __rcu *next;
+ void (*write)(const void *, unsigned int);
+};
+
+int register_ftrace_export(struct trace_export *export);
+int unregister_ftrace_export(struct trace_export *export);
+
+#endif /* CONFIG_TRACING */
+
+#endif /* _LINUX_TRACE_H */
diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h
index 4ac89acb6136..a03192052066 100644
--- a/include/linux/tracepoint-defs.h
+++ b/include/linux/tracepoint-defs.h
@@ -29,7 +29,7 @@ struct tracepoint_func {
struct tracepoint {
const char *name; /* Tracepoint name */
struct static_key key;
- void (*regfunc)(void);
+ int (*regfunc)(void);
void (*unregfunc)(void);
struct tracepoint_func __rcu *funcs;
};
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index be586c632a0c..f72fcfe0e66a 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -81,7 +81,7 @@ static inline void tracepoint_synchronize_unregister(void)
}
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
-extern void syscall_regfunc(void);
+extern int syscall_regfunc(void);
extern void syscall_unregfunc(void);
#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */
diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
index 92a7d85917b4..b49258b16f4e 100644
--- a/include/rdma/ib_cm.h
+++ b/include/rdma/ib_cm.h
@@ -603,4 +603,10 @@ struct ib_cm_sidr_rep_param {
int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
struct ib_cm_sidr_rep_param *param);
+/**
+ * ibcm_reject_msg - return a pointer to a reject message string.
+ * @reason: Value returned in the REJECT event status field.
+ */
+const char *__attribute_const__ ibcm_reject_msg(int reason);
+
#endif /* IB_CM_H */
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index c8a773ffe23b..981214b3790c 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -46,7 +46,7 @@
#define IB_MGMT_BASE_VERSION 1
#define OPA_MGMT_BASE_VERSION 0x80
-#define OPA_SMP_CLASS_VERSION 0x80
+#define OPA_SM_CLASS_VERSION 0x80
/* Management classes */
#define IB_MGMT_CLASS_SUBN_LID_ROUTED 0x01
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 5ad43a487745..8029d2a51f14 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1102,6 +1102,7 @@ enum ib_qp_attr_mask {
IB_QP_RESERVED2 = (1<<22),
IB_QP_RESERVED3 = (1<<23),
IB_QP_RESERVED4 = (1<<24),
+ IB_QP_RATE_LIMIT = (1<<25),
};
enum ib_qp_state {
@@ -1151,6 +1152,7 @@ struct ib_qp_attr {
u8 rnr_retry;
u8 alt_port_num;
u8 alt_timeout;
+ u32 rate_limit;
};
enum ib_wr_opcode {
@@ -1592,17 +1594,19 @@ enum ib_flow_attr_type {
/* Supported steering header types */
enum ib_flow_spec_type {
/* L2 headers*/
- IB_FLOW_SPEC_ETH = 0x20,
- IB_FLOW_SPEC_IB = 0x22,
+ IB_FLOW_SPEC_ETH = 0x20,
+ IB_FLOW_SPEC_IB = 0x22,
/* L3 header*/
- IB_FLOW_SPEC_IPV4 = 0x30,
- IB_FLOW_SPEC_IPV6 = 0x31,
+ IB_FLOW_SPEC_IPV4 = 0x30,
+ IB_FLOW_SPEC_IPV6 = 0x31,
/* L4 headers*/
- IB_FLOW_SPEC_TCP = 0x40,
- IB_FLOW_SPEC_UDP = 0x41
+ IB_FLOW_SPEC_TCP = 0x40,
+ IB_FLOW_SPEC_UDP = 0x41,
+ IB_FLOW_SPEC_VXLAN_TUNNEL = 0x50,
+ IB_FLOW_SPEC_INNER = 0x100,
};
#define IB_FLOW_SPEC_LAYER_MASK 0xF0
-#define IB_FLOW_SPEC_SUPPORT_LAYERS 4
+#define IB_FLOW_SPEC_SUPPORT_LAYERS 8
/* Flow steering rule priority is set according to it's domain.
* Lower domain value means higher priority.
@@ -1630,7 +1634,7 @@ struct ib_flow_eth_filter {
};
struct ib_flow_spec_eth {
- enum ib_flow_spec_type type;
+ u32 type;
u16 size;
struct ib_flow_eth_filter val;
struct ib_flow_eth_filter mask;
@@ -1644,7 +1648,7 @@ struct ib_flow_ib_filter {
};
struct ib_flow_spec_ib {
- enum ib_flow_spec_type type;
+ u32 type;
u16 size;
struct ib_flow_ib_filter val;
struct ib_flow_ib_filter mask;
@@ -1669,7 +1673,7 @@ struct ib_flow_ipv4_filter {
};
struct ib_flow_spec_ipv4 {
- enum ib_flow_spec_type type;
+ u32 type;
u16 size;
struct ib_flow_ipv4_filter val;
struct ib_flow_ipv4_filter mask;
@@ -1687,7 +1691,7 @@ struct ib_flow_ipv6_filter {
};
struct ib_flow_spec_ipv6 {
- enum ib_flow_spec_type type;
+ u32 type;
u16 size;
struct ib_flow_ipv6_filter val;
struct ib_flow_ipv6_filter mask;
@@ -1701,15 +1705,30 @@ struct ib_flow_tcp_udp_filter {
};
struct ib_flow_spec_tcp_udp {
- enum ib_flow_spec_type type;
+ u32 type;
u16 size;
struct ib_flow_tcp_udp_filter val;
struct ib_flow_tcp_udp_filter mask;
};
+struct ib_flow_tunnel_filter {
+ __be32 tunnel_id;
+ u8 real_sz[0];
+};
+
+/* ib_flow_spec_tunnel describes the Vxlan tunnel
+ * the tunnel_id from val has the vni value
+ */
+struct ib_flow_spec_tunnel {
+ u32 type;
+ u16 size;
+ struct ib_flow_tunnel_filter val;
+ struct ib_flow_tunnel_filter mask;
+};
+
union ib_flow_spec {
struct {
- enum ib_flow_spec_type type;
+ u32 type;
u16 size;
};
struct ib_flow_spec_eth eth;
@@ -1717,6 +1736,7 @@ union ib_flow_spec {
struct ib_flow_spec_ipv4 ipv4;
struct ib_flow_spec_tcp_udp tcp_udp;
struct ib_flow_spec_ipv6 ipv6;
+ struct ib_flow_spec_tunnel tunnel;
};
struct ib_flow_attr {
@@ -1933,7 +1953,8 @@ struct ib_device {
struct ib_udata *udata);
int (*dealloc_pd)(struct ib_pd *pd);
struct ib_ah * (*create_ah)(struct ib_pd *pd,
- struct ib_ah_attr *ah_attr);
+ struct ib_ah_attr *ah_attr,
+ struct ib_udata *udata);
int (*modify_ah)(struct ib_ah *ah,
struct ib_ah_attr *ah_attr);
int (*query_ah)(struct ib_ah *ah,
@@ -2581,6 +2602,24 @@ void ib_dealloc_pd(struct ib_pd *pd);
struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
/**
+ * ib_get_gids_from_rdma_hdr - Get sgid and dgid from GRH or IPv4 header
+ * work completion.
+ * @hdr: the L3 header to parse
+ * @net_type: type of header to parse
+ * @sgid: place to store source gid
+ * @dgid: place to store destination gid
+ */
+int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr,
+ enum rdma_network_type net_type,
+ union ib_gid *sgid, union ib_gid *dgid);
+
+/**
+ * ib_get_rdma_header_version - Get the header version
+ * @hdr: the L3 header to parse
+ */
+int ib_get_rdma_header_version(const union rdma_network_hdr *hdr);
+
+/**
* ib_init_ah_from_wc - Initializes address handle attributes from a
* work completion.
* @device: Device on which the received message arrived.
@@ -3357,4 +3396,7 @@ int ib_sg_to_pages(struct ib_mr *mr, struct scatterlist *sgl, int sg_nents,
void ib_drain_rq(struct ib_qp *qp);
void ib_drain_sq(struct ib_qp *qp);
void ib_drain_qp(struct ib_qp *qp);
+
+int ib_resolve_eth_dmac(struct ib_device *device,
+ struct ib_ah_attr *ah_attr);
#endif /* IB_VERBS_H */
diff --git a/include/rdma/iw_cm.h b/include/rdma/iw_cm.h
index 6d0065c322b7..5cd7701db148 100644
--- a/include/rdma/iw_cm.h
+++ b/include/rdma/iw_cm.h
@@ -253,4 +253,10 @@ int iw_cm_disconnect(struct iw_cm_id *cm_id, int abrupt);
int iw_cm_init_qp_attr(struct iw_cm_id *cm_id, struct ib_qp_attr *qp_attr,
int *qp_attr_mask);
+/**
+ * iwcm_reject_msg - return a pointer to a reject message string.
+ * @reason: Value returned in the REJECT event status field.
+ */
+const char *__attribute_const__ iwcm_reject_msg(int reason);
+
#endif /* IW_CM_H */
diff --git a/include/rdma/opa_smi.h b/include/rdma/opa_smi.h
index 4a529ef47995..f7896117936e 100644
--- a/include/rdma/opa_smi.h
+++ b/include/rdma/opa_smi.h
@@ -44,8 +44,6 @@
#define OPA_MAX_SLS 32
#define OPA_MAX_SCS 32
-#define OPA_SMI_CLASS_VERSION 0x80
-
#define OPA_LID_PERMISSIVE cpu_to_be32(0xFFFFFFFF)
struct opa_smp {
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 81fb1d15e8bb..d3968b561f86 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -388,4 +388,29 @@ int rdma_set_afonly(struct rdma_cm_id *id, int afonly);
*/
__be64 rdma_get_service_id(struct rdma_cm_id *id, struct sockaddr *addr);
+/**
+ * rdma_reject_msg - return a pointer to a reject message string.
+ * @id: Communication identifier that received the REJECT event.
+ * @reason: Value returned in the REJECT event status field.
+ */
+const char *__attribute_const__ rdma_reject_msg(struct rdma_cm_id *id,
+ int reason);
+/**
+ * rdma_is_consumer_reject - return true if the consumer rejected the connect
+ * request.
+ * @id: Communication identifier that received the REJECT event.
+ * @reason: Value returned in the REJECT event status field.
+ */
+bool rdma_is_consumer_reject(struct rdma_cm_id *id, int reason);
+
+/**
+ * rdma_consumer_reject_data - return the consumer reject private data and
+ * length, if any.
+ * @id: Communication identifier that received the REJECT event.
+ * @ev: RDMA CM reject event.
+ * @data_len: Pointer to the resulting length of the consumer data.
+ */
+const void *rdma_consumer_reject_data(struct rdma_cm_id *id,
+ struct rdma_cm_event *ev, u8 *data_len);
+
#endif /* RDMA_CM_H */
diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h
index e31502107a58..861e23eaebda 100644
--- a/include/rdma/rdma_vt.h
+++ b/include/rdma/rdma_vt.h
@@ -185,6 +185,27 @@ struct rvt_driver_provided {
* check_support() for details.
*/
+ /* hot path calldowns in a single cacheline */
+
+ /*
+ * Give the driver a notice that there is send work to do. It is up to
+ * the driver to generally push the packets out, this just queues the
+ * work with the driver. There are two variants here. The no_lock
+ * version requires the s_lock not to be held. The other assumes the
+ * s_lock is held.
+ */
+ void (*schedule_send)(struct rvt_qp *qp);
+ void (*schedule_send_no_lock)(struct rvt_qp *qp);
+
+ /* Driver specific work request checking */
+ int (*check_send_wqe)(struct rvt_qp *qp, struct rvt_swqe *wqe);
+
+ /*
+ * Sometimes rdmavt needs to kick the driver's send progress. That is
+ * done by this call back.
+ */
+ void (*do_send)(struct rvt_qp *qp);
+
/* Passed to ib core registration. Callback to create syfs files */
int (*port_callback)(struct ib_device *, u8, struct kobject *);
@@ -223,22 +244,6 @@ struct rvt_driver_provided {
void (*notify_qp_reset)(struct rvt_qp *qp);
/*
- * Give the driver a notice that there is send work to do. It is up to
- * the driver to generally push the packets out, this just queues the
- * work with the driver. There are two variants here. The no_lock
- * version requires the s_lock not to be held. The other assumes the
- * s_lock is held.
- */
- void (*schedule_send)(struct rvt_qp *qp);
- void (*schedule_send_no_lock)(struct rvt_qp *qp);
-
- /*
- * Sometimes rdmavt needs to kick the driver's send progress. That is
- * done by this call back.
- */
- void (*do_send)(struct rvt_qp *qp);
-
- /*
* Get a path mtu from the driver based on qp attributes.
*/
int (*get_pmtu_from_attr)(struct rvt_dev_info *rdi, struct rvt_qp *qp,
@@ -324,9 +329,6 @@ struct rvt_driver_provided {
void (*modify_qp)(struct rvt_qp *qp, struct ib_qp_attr *attr,
int attr_mask, struct ib_udata *udata);
- /* Driver specific work request checking */
- int (*check_send_wqe)(struct rvt_qp *qp, struct rvt_swqe *wqe);
-
/* Notify driver a mad agent has been created */
void (*notify_create_mad_agent)(struct rvt_dev_info *rdi, int port_idx);
@@ -355,12 +357,12 @@ struct rvt_dev_info {
/* post send table */
const struct rvt_operation_params *post_parms;
- struct rvt_mregion __rcu *dma_mr;
- struct rvt_lkey_table lkey_table;
-
/* Driver specific helper functions */
struct rvt_driver_provided driver_f;
+ struct rvt_mregion __rcu *dma_mr;
+ struct rvt_lkey_table lkey_table;
+
/* Internal use */
int n_pds_allocated;
spinlock_t n_pds_lock; /* Protect pd allocated count */
diff --git a/include/rdma/rdmavt_mr.h b/include/rdma/rdmavt_mr.h
index 6b3c6c8b6b77..de59de28b6a2 100644
--- a/include/rdma/rdmavt_mr.h
+++ b/include/rdma/rdmavt_mr.h
@@ -90,11 +90,15 @@ struct rvt_mregion {
#define RVT_MAX_LKEY_TABLE_BITS 23
struct rvt_lkey_table {
- spinlock_t lock; /* protect changes in this struct */
- u32 next; /* next unused index (speeds search) */
- u32 gen; /* generation count */
+ /* read mostly fields */
u32 max; /* size of the table */
+ u32 shift; /* lkey/rkey shift */
struct rvt_mregion __rcu **table;
+ /* writeable fields */
+ /* protect changes in this struct */
+ spinlock_t lock ____cacheline_aligned_in_smp;
+ u32 next; /* next unused index (speeds search) */
+ u32 gen; /* generation count */
};
/*
diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h
index 2c5183ef0243..f3dbd157ae5c 100644
--- a/include/rdma/rdmavt_qp.h
+++ b/include/rdma/rdmavt_qp.h
@@ -51,6 +51,7 @@
#include <rdma/rdma_vt.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_verbs.h>
+#include <rdma/rdmavt_cq.h>
/*
* Atomic bit definitions for r_aflags.
*/
@@ -485,6 +486,23 @@ static inline void rvt_put_qp(struct rvt_qp *qp)
}
/**
+ * rvt_put_swqe - drop mr refs held by swqe
+ * @wqe - the send wqe
+ *
+ * This drops any mr references held by the swqe
+ */
+static inline void rvt_put_swqe(struct rvt_swqe *wqe)
+{
+ int i;
+
+ for (i = 0; i < wqe->wr.num_sge; i++) {
+ struct rvt_sge *sge = &wqe->sg_list[i];
+
+ rvt_put_mr(sge->mr);
+ }
+}
+
+/**
* rvt_qp_wqe_reserve - reserve operation
* @qp - the rvt qp
* @wqe - the send wqe
@@ -527,6 +545,65 @@ static inline void rvt_qp_wqe_unreserve(
}
}
+extern const enum ib_wc_opcode ib_rvt_wc_opcode[];
+
+/**
+ * rvt_qp_swqe_complete() - insert send completion
+ * @qp - the qp
+ * @wqe - the send wqe
+ * @status - completion status
+ *
+ * Insert a send completion into the completion
+ * queue if the qp indicates it should be done.
+ *
+ * See IBTA 10.7.3.1 for info on completion
+ * control.
+ */
+static inline void rvt_qp_swqe_complete(
+ struct rvt_qp *qp,
+ struct rvt_swqe *wqe,
+ enum ib_wc_status status)
+{
+ if (unlikely(wqe->wr.send_flags & RVT_SEND_RESERVE_USED))
+ return;
+ if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
+ (wqe->wr.send_flags & IB_SEND_SIGNALED) ||
+ status != IB_WC_SUCCESS) {
+ struct ib_wc wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.wr_id = wqe->wr.wr_id;
+ wc.status = status;
+ wc.opcode = ib_rvt_wc_opcode[wqe->wr.opcode];
+ wc.qp = &qp->ibqp;
+ wc.byte_len = wqe->length;
+ rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc,
+ status != IB_WC_SUCCESS);
+ }
+}
+
+/**
+ * @qp - the qp pair
+ * @len - the length
+ *
+ * Perform a shift based mtu round up divide
+ */
+static inline u32 rvt_div_round_up_mtu(struct rvt_qp *qp, u32 len)
+{
+ return (len + qp->pmtu - 1) >> qp->log_pmtu;
+}
+
+/**
+ * @qp - the qp pair
+ * @len - the length
+ *
+ * Perform a shift based mtu divide
+ */
+static inline u32 rvt_div_mtu(struct rvt_qp *qp, u32 len)
+{
+ return len >> qp->log_pmtu;
+}
+
extern const int ib_rvt_state_ops[];
struct rvt_dev_info;
diff --git a/include/soc/arc/aux.h b/include/soc/arc/aux.h
new file mode 100644
index 000000000000..8c3fb13e0452
--- /dev/null
+++ b/include/soc/arc/aux.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016-2017 Synopsys, Inc. (www.synopsys.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 __SOC_ARC_AUX_H__
+#define __SOC_ARC_AUX_H__
+
+#ifdef CONFIG_ARC
+
+#define read_aux_reg(r) __builtin_arc_lr(r)
+
+/* gcc builtin sr needs reg param to be long immediate */
+#define write_aux_reg(r, v) __builtin_arc_sr((unsigned int)(v), r)
+
+#else /* !CONFIG_ARC */
+
+static inline int read_aux_reg(u32 r)
+{
+ return 0;
+}
+
+/*
+ * function helps elide unused variable warning
+ * see: http://lists.infradead.org/pipermail/linux-snps-arc/2016-November/001748.html
+ */
+static inline void write_aux_reg(u32 r, u32 v)
+{
+ ;
+}
+
+#endif
+
+#define READ_BCR(reg, into) \
+{ \
+ unsigned int tmp; \
+ tmp = read_aux_reg(reg); \
+ if (sizeof(tmp) == sizeof(into)) { \
+ into = *((typeof(into) *)&tmp); \
+ } else { \
+ extern void bogus_undefined(void); \
+ bogus_undefined(); \
+ } \
+}
+
+#define WRITE_AUX(reg, into) \
+{ \
+ unsigned int tmp; \
+ if (sizeof(tmp) == sizeof(into)) { \
+ tmp = (*(unsigned int *)&(into)); \
+ write_aux_reg(reg, tmp); \
+ } else { \
+ extern void bogus_undefined(void); \
+ bogus_undefined(); \
+ } \
+}
+
+
+#endif
diff --git a/arch/arc/include/asm/mcip.h b/include/soc/arc/mcip.h
index c8fbe4114bad..6902c2a8bd23 100644
--- a/arch/arc/include/asm/mcip.h
+++ b/include/soc/arc/mcip.h
@@ -8,12 +8,10 @@
* published by the Free Software Foundation.
*/
-#ifndef __ASM_MCIP_H
-#define __ASM_MCIP_H
+#ifndef __SOC_ARC_MCIP_H
+#define __SOC_ARC_MCIP_H
-#ifdef CONFIG_ISA_ARCV2
-
-#include <asm/arcregs.h>
+#include <soc/arc/aux.h>
#define ARC_REG_MCIP_BCR 0x0d0
#define ARC_REG_MCIP_CMD 0x600
@@ -103,5 +101,3 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
}
#endif
-
-#endif
diff --git a/include/soc/arc/timers.h b/include/soc/arc/timers.h
new file mode 100644
index 000000000000..a20ed2fbc432
--- /dev/null
+++ b/include/soc/arc/timers.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.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 __SOC_ARC_TIMERS_H
+#define __SOC_ARC_TIMERS_H
+
+#include <soc/arc/aux.h>
+
+/* Timer related Aux registers */
+#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
+#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
+#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
+#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
+#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
+#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
+
+/* CTRL reg bits */
+#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */
+#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
+
+#define ARC_TIMERN_MAX 0xFFFFFFFF
+
+#define ARC_REG_TIMERS_BCR 0x75
+
+struct bcr_timer {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
+#else
+ unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
+#endif
+};
+
+#endif
diff --git a/include/soc/at91/atmel-secumod.h b/include/soc/at91/atmel-secumod.h
new file mode 100644
index 000000000000..22cd5d506926
--- /dev/null
+++ b/include/soc/at91/atmel-secumod.h
@@ -0,0 +1,19 @@
+/*
+ * Atmel Security Module register offsets and bit definitions.
+ *
+ * Copyright (C) 2016 Atmel
+ *
+ * Author: Alexandre Belloni <alexandre.belloni@free-electrons.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 _LINUX_SOC_AT91_ATMEL_SECUMOD_H
+#define _LINUX_SOC_AT91_ATMEL_SECUMOD_H
+
+#define AT91_SECUMOD_RAMRDY 0x14
+#define AT91_SECUMOD_RAMRDY_READY BIT(0)
+
+#endif /* _LINUX_SOC_AT91_ATMEL_SECUMOD_H */
diff --git a/include/soc/nps/mtm.h b/include/soc/nps/mtm.h
new file mode 100644
index 000000000000..d2f5e7e3703e
--- /dev/null
+++ b/include/soc/nps/mtm.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, 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 SOC_NPS_MTM_H
+#define SOC_NPS_MTM_H
+
+#define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF
+#define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3
+
+static inline void hw_schd_save(unsigned int *flags)
+{
+ __asm__ __volatile__(
+ " .word %1\n"
+ " st r3,[%0]\n"
+ :
+ : "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
+ : "r3", "memory");
+}
+
+static inline void hw_schd_restore(unsigned int flags)
+{
+ __asm__ __volatile__(
+ " mov r3, %0\n"
+ " .word %1\n"
+ :
+ : "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
+ : "r3");
+}
+
+#endif /* SOC_NPS_MTM_H */
diff --git a/include/soc/tegra/bpmp-abi.h b/include/soc/tegra/bpmp-abi.h
new file mode 100644
index 000000000000..0aaef5960e29
--- /dev/null
+++ b/include/soc/tegra/bpmp-abi.h
@@ -0,0 +1,1601 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ABI_BPMP_ABI_H_
+#define _ABI_BPMP_ABI_H_
+
+#ifdef LK
+#include <stdint.h>
+#endif
+
+#ifndef __ABI_PACKED
+#define __ABI_PACKED __attribute__((packed))
+#endif
+
+#ifdef NO_GCC_EXTENSIONS
+#define EMPTY char empty;
+#define EMPTY_ARRAY 1
+#else
+#define EMPTY
+#define EMPTY_ARRAY 0
+#endif
+
+#ifndef __UNION_ANON
+#define __UNION_ANON
+#endif
+/**
+ * @file
+ */
+
+
+/**
+ * @defgroup MRQ MRQ Messages
+ * @brief Messages sent to/from BPMP via IPC
+ * @{
+ * @defgroup MRQ_Format Message Format
+ * @defgroup MRQ_Codes Message Request (MRQ) Codes
+ * @defgroup MRQ_Payloads Message Payloads
+ * @defgroup Error_Codes Error Codes
+ * @}
+ */
+
+/**
+ * @addtogroup MRQ_Format Message Format
+ * @{
+ * The CPU requests the BPMP to perform a particular service by
+ * sending it an IVC frame containing a single MRQ message. An MRQ
+ * message consists of a @ref mrq_request followed by a payload whose
+ * format depends on mrq_request::mrq.
+ *
+ * The BPMP processes the data and replies with an IVC frame (on the
+ * same IVC channel) containing and MRQ response. An MRQ response
+ * consists of a @ref mrq_response followed by a payload whose format
+ * depends on the associated mrq_request::mrq.
+ *
+ * A well-defined subset of the MRQ messages that the CPU sends to the
+ * BPMP can lead to BPMP eventually sending an MRQ message to the
+ * CPU. For example, when the CPU uses an #MRQ_THERMAL message to set
+ * a thermal trip point, the BPMP may eventually send a single
+ * #MRQ_THERMAL message of its own to the CPU indicating that the trip
+ * point has been crossed.
+ * @}
+ */
+
+/**
+ * @ingroup MRQ_Format
+ * @brief header for an MRQ message
+ *
+ * Provides the MRQ number for the MRQ message: #mrq. The remainder of
+ * the MRQ message is a payload (immediately following the
+ * mrq_request) whose format depends on mrq.
+ *
+ * @todo document the flags
+ */
+struct mrq_request {
+ /** @brief MRQ number of the request */
+ uint32_t mrq;
+ /** @brief flags for the request */
+ uint32_t flags;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Format
+ * @brief header for an MRQ response
+ *
+ * Provides an error code for the associated MRQ message. The
+ * remainder of the MRQ response is a payload (immediately following
+ * the mrq_response) whose format depends on the associated
+ * mrq_request::mrq
+ *
+ * @todo document the flags
+ */
+struct mrq_response {
+ /** @brief error code for the MRQ request itself */
+ int32_t err;
+ /** @brief flags for the response */
+ uint32_t flags;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Format
+ * Minimum needed size for an IPC message buffer
+ */
+#define MSG_MIN_SZ 128
+/**
+ * @ingroup MRQ_Format
+ * Minimum size guaranteed for data in an IPC message buffer
+ */
+#define MSG_DATA_MIN_SZ 120
+
+/**
+ * @ingroup MRQ_Codes
+ * @name Legal MRQ codes
+ * These are the legal values for mrq_request::mrq
+ * @{
+ */
+
+#define MRQ_PING 0
+#define MRQ_QUERY_TAG 1
+#define MRQ_MODULE_LOAD 4
+#define MRQ_MODULE_UNLOAD 5
+#define MRQ_TRACE_MODIFY 7
+#define MRQ_WRITE_TRACE 8
+#define MRQ_THREADED_PING 9
+#define MRQ_MODULE_MAIL 11
+#define MRQ_DEBUGFS 19
+#define MRQ_RESET 20
+#define MRQ_I2C 21
+#define MRQ_CLK 22
+#define MRQ_QUERY_ABI 23
+#define MRQ_PG_READ_STATE 25
+#define MRQ_PG_UPDATE_STATE 26
+#define MRQ_THERMAL 27
+#define MRQ_CPU_VHINT 28
+#define MRQ_ABI_RATCHET 29
+#define MRQ_EMC_DVFS_LATENCY 31
+#define MRQ_TRACE_ITER 64
+
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @brief Maximum MRQ code to be sent by CPU software to
+ * BPMP. Subject to change in future
+ */
+#define MAX_CPU_MRQ_ID 64
+
+/**
+ * @addtogroup MRQ_Payloads Message Payloads
+ * @{
+ * @defgroup Ping
+ * @defgroup Query_Tag Query Tag
+ * @defgroup Module Loadable Modules
+ * @defgroup Trace
+ * @defgroup Debugfs
+ * @defgroup Reset
+ * @defgroup I2C
+ * @defgroup Clocks
+ * @defgroup ABI_info ABI Info
+ * @defgroup MC_Flush MC Flush
+ * @defgroup Powergating
+ * @defgroup Thermal
+ * @defgroup Vhint CPU Voltage hint
+ * @defgroup MRQ_Deprecated Deprecated MRQ messages
+ * @defgroup EMC
+ * @}
+ */
+
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_PING
+ * @brief A simple ping
+ *
+ * * Platforms: All
+ * * Initiators: Any
+ * * Targets: Any
+ * * Request Payload: @ref mrq_ping_request
+ * * Response Payload: @ref mrq_ping_response
+ *
+ * @ingroup MRQ_Codes
+ * @def MRQ_THREADED_PING
+ * @brief A deeper ping
+ *
+ * * Platforms: All
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_ping_request
+ * * Response Payload: @ref mrq_ping_response
+ *
+ * Behavior is equivalent to a simple #MRQ_PING except that BPMP
+ * responds from a thread context (providing a slightly more robust
+ * sign of life).
+ *
+ */
+
+/**
+ * @ingroup Ping
+ * @brief request with #MRQ_PING
+ *
+ * Used by the sender of an #MRQ_PING message to request a pong from
+ * recipient. The response from the recipient is computed based on
+ * #challenge.
+ */
+struct mrq_ping_request {
+/** @brief arbitrarily chosen value */
+ uint32_t challenge;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Ping
+ * @brief response to #MRQ_PING
+ *
+ * Sent in response to an #MRQ_PING message. #reply should be the
+ * mrq_ping_request challenge left shifted by 1 with the carry-bit
+ * dropped.
+ *
+ */
+struct mrq_ping_response {
+ /** @brief response to the MRQ_PING challege */
+ uint32_t reply;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_QUERY_TAG
+ * @brief Query BPMP firmware's tag (i.e. version information)
+ *
+ * * Platforms: All
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_query_tag_request
+ * * Response Payload: N/A
+ *
+ */
+
+/**
+ * @ingroup Query_Tag
+ * @brief request with #MRQ_QUERY_TAG
+ *
+ * Used by #MRQ_QUERY_TAG call to ask BPMP to fill in the memory
+ * pointed by #addr with BPMP firmware header.
+ *
+ * The sender is reponsible for ensuring that #addr is mapped in to
+ * the recipient's address map.
+ */
+struct mrq_query_tag_request {
+ /** @brief base address to store the firmware header */
+ uint32_t addr;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_MODULE_LOAD
+ * @brief dynamically load a BPMP code module
+ *
+ * * Platforms: All
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_module_load_request
+ * * Response Payload: @ref mrq_module_load_response
+ *
+ * @note This MRQ is disabled on production systems
+ *
+ */
+
+/**
+ * @ingroup Module
+ * @brief request with #MRQ_MODULE_LOAD
+ *
+ * Used by #MRQ_MODULE_LOAD calls to ask the recipient to dynamically
+ * load the code located at #phys_addr and having size #size
+ * bytes. #phys_addr is treated as a void pointer.
+ *
+ * The recipient copies the code from #phys_addr to locally allocated
+ * memory prior to responding to this message.
+ *
+ * @todo document the module header format
+ *
+ * The sender is responsible for ensuring that the code is mapped in
+ * the recipient's address map.
+ *
+ */
+struct mrq_module_load_request {
+ /** @brief base address of the code to load. Treated as (void *) */
+ uint32_t phys_addr; /* (void *) */
+ /** @brief size in bytes of code to load */
+ uint32_t size;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Module
+ * @brief response to #MRQ_MODULE_LOAD
+ *
+ * @todo document mrq_response::err
+ */
+struct mrq_module_load_response {
+ /** @brief handle to the loaded module */
+ uint32_t base;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_MODULE_UNLOAD
+ * @brief unload a previously loaded code module
+ *
+ * * Platforms: All
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_module_unload_request
+ * * Response Payload: N/A
+ *
+ * @note This MRQ is disabled on production systems
+ */
+
+/**
+ * @ingroup Module
+ * @brief request with #MRQ_MODULE_UNLOAD
+ *
+ * Used by #MRQ_MODULE_UNLOAD calls to request that a previously loaded
+ * module be unloaded.
+ */
+struct mrq_module_unload_request {
+ /** @brief handle of the module to unload */
+ uint32_t base;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_TRACE_MODIFY
+ * @brief modify the set of enabled trace events
+ *
+ * * Platforms: All
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_trace_modify_request
+ * * Response Payload: @ref mrq_trace_modify_response
+ *
+ * @note This MRQ is disabled on production systems
+ */
+
+/**
+ * @ingroup Trace
+ * @brief request with #MRQ_TRACE_MODIFY
+ *
+ * Used by %MRQ_TRACE_MODIFY calls to enable or disable specify trace
+ * events. #set takes precedence for any bit set in both #set and
+ * #clr.
+ */
+struct mrq_trace_modify_request {
+ /** @brief bit mask of trace events to disable */
+ uint32_t clr;
+ /** @brief bit mask of trace events to enable */
+ uint32_t set;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Trace
+ * @brief response to #MRQ_TRACE_MODIFY
+ *
+ * Sent in repsonse to an #MRQ_TRACE_MODIFY message. #mask reflects the
+ * state of which events are enabled after the recipient acted on the
+ * message.
+ *
+ */
+struct mrq_trace_modify_response {
+ /** @brief bit mask of trace event enable states */
+ uint32_t mask;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_WRITE_TRACE
+ * @brief Write trace data to a buffer
+ *
+ * * Platforms: All
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_write_trace_request
+ * * Response Payload: @ref mrq_write_trace_response
+ *
+ * mrq_response::err depends on the @ref mrq_write_trace_request field
+ * values. err is -#BPMP_EINVAL if size is zero or area is NULL or
+ * area is in an illegal range. A positive value for err indicates the
+ * number of bytes written to area.
+ *
+ * @note This MRQ is disabled on production systems
+ */
+
+/**
+ * @ingroup Trace
+ * @brief request with #MRQ_WRITE_TRACE
+ *
+ * Used by MRQ_WRITE_TRACE calls to ask the recipient to copy trace
+ * data from the recipient's local buffer to the output buffer. #area
+ * is treated as a byte-aligned pointer in the recipient's address
+ * space.
+ *
+ * The sender is responsible for ensuring that the output
+ * buffer is mapped in the recipient's address map. The recipient is
+ * responsible for protecting its own code and data from accidental
+ * overwrites.
+ */
+struct mrq_write_trace_request {
+ /** @brief base address of output buffer */
+ uint32_t area;
+ /** @brief size in bytes of the output buffer */
+ uint32_t size;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Trace
+ * @brief response to #MRQ_WRITE_TRACE
+ *
+ * Once this response is sent, the respondent will not access the
+ * output buffer further.
+ */
+struct mrq_write_trace_response {
+ /**
+ * @brief flag whether more data remains in local buffer
+ *
+ * Value is 1 if the entire local trace buffer has been
+ * drained to the outputbuffer. Value is 0 otherwise.
+ */
+ uint32_t eof;
+} __ABI_PACKED;
+
+/** @private */
+struct mrq_threaded_ping_request {
+ uint32_t challenge;
+} __ABI_PACKED;
+
+/** @private */
+struct mrq_threaded_ping_response {
+ uint32_t reply;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_MODULE_MAIL
+ * @brief send a message to a loadable module
+ *
+ * * Platforms: All
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_module_mail_request
+ * * Response Payload: @ref mrq_module_mail_response
+ *
+ * @note This MRQ is disabled on production systems
+ */
+
+/**
+ * @ingroup Module
+ * @brief request with #MRQ_MODULE_MAIL
+ */
+struct mrq_module_mail_request {
+ /** @brief handle to the previously loaded module */
+ uint32_t base;
+ /** @brief module-specific mail payload
+ *
+ * The length of data[ ] is unknown to the BPMP core firmware
+ * but it is limited to the size of an IPC message.
+ */
+ uint8_t data[EMPTY_ARRAY];
+} __ABI_PACKED;
+
+/**
+ * @ingroup Module
+ * @brief response to #MRQ_MODULE_MAIL
+ */
+struct mrq_module_mail_response {
+ /** @brief module-specific mail payload
+ *
+ * The length of data[ ] is unknown to the BPMP core firmware
+ * but it is limited to the size of an IPC message.
+ */
+ uint8_t data[EMPTY_ARRAY];
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_DEBUGFS
+ * @brief Interact with BPMP's debugfs file nodes
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_debugfs_request
+ * * Response Payload: @ref mrq_debugfs_response
+ */
+
+/**
+ * @addtogroup Debugfs
+ * @{
+ *
+ * The BPMP firmware implements a pseudo-filesystem called
+ * debugfs. Any driver within the firmware may register with debugfs
+ * to expose an arbitrary set of "files" in the filesystem. When
+ * software on the CPU writes to a debugfs file, debugfs passes the
+ * written data to a callback provided by the driver. When software on
+ * the CPU reads a debugfs file, debugfs queries the driver for the
+ * data to return to the CPU. The intention of the debugfs filesystem
+ * is to provide information useful for debugging the system at
+ * runtime.
+ *
+ * @note The files exposed via debugfs are not part of the
+ * BPMP firmware's ABI. debugfs files may be added or removed in any
+ * given version of the firmware. Typically the semantics of a debugfs
+ * file are consistent from version to version but even that is not
+ * guaranteed.
+ *
+ * @}
+ */
+/** @ingroup Debugfs */
+enum mrq_debugfs_commands {
+ CMD_DEBUGFS_READ = 1,
+ CMD_DEBUGFS_WRITE = 2,
+ CMD_DEBUGFS_DUMPDIR = 3,
+ CMD_DEBUGFS_MAX
+};
+
+/**
+ * @ingroup Debugfs
+ * @brief parameters for CMD_DEBUGFS_READ/WRITE command
+ */
+struct cmd_debugfs_fileop_request {
+ /** @brief physical address pointing at filename */
+ uint32_t fnameaddr;
+ /** @brief length in bytes of filename buffer */
+ uint32_t fnamelen;
+ /** @brief physical address pointing to data buffer */
+ uint32_t dataaddr;
+ /** @brief length in bytes of data buffer */
+ uint32_t datalen;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Debugfs
+ * @brief parameters for CMD_DEBUGFS_READ/WRITE command
+ */
+struct cmd_debugfs_dumpdir_request {
+ /** @brief physical address pointing to data buffer */
+ uint32_t dataaddr;
+ /** @brief length in bytes of data buffer */
+ uint32_t datalen;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Debugfs
+ * @brief response data for CMD_DEBUGFS_READ/WRITE command
+ */
+struct cmd_debugfs_fileop_response {
+ /** @brief always 0 */
+ uint32_t reserved;
+ /** @brief number of bytes read from or written to data buffer */
+ uint32_t nbytes;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Debugfs
+ * @brief response data for CMD_DEBUGFS_DUMPDIR command
+ */
+struct cmd_debugfs_dumpdir_response {
+ /** @brief always 0 */
+ uint32_t reserved;
+ /** @brief number of bytes read from or written to data buffer */
+ uint32_t nbytes;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Debugfs
+ * @brief request with #MRQ_DEBUGFS.
+ *
+ * The sender of an MRQ_DEBUGFS message uses #cmd to specify a debugfs
+ * command to execute. Legal commands are the values of @ref
+ * mrq_debugfs_commands. Each command requires a specific additional
+ * payload of data.
+ *
+ * |command |payload|
+ * |-------------------|-------|
+ * |CMD_DEBUGFS_READ |fop |
+ * |CMD_DEBUGFS_WRITE |fop |
+ * |CMD_DEBUGFS_DUMPDIR|dumpdir|
+ */
+struct mrq_debugfs_request {
+ uint32_t cmd;
+ union {
+ struct cmd_debugfs_fileop_request fop;
+ struct cmd_debugfs_dumpdir_request dumpdir;
+ } __UNION_ANON;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Debugfs
+ */
+struct mrq_debugfs_response {
+ /** @brief always 0 */
+ int32_t reserved;
+ union {
+ /** @brief response data for CMD_DEBUGFS_READ OR
+ * CMD_DEBUGFS_WRITE command
+ */
+ struct cmd_debugfs_fileop_response fop;
+ /** @brief response data for CMD_DEBUGFS_DUMPDIR command */
+ struct cmd_debugfs_dumpdir_response dumpdir;
+ } __UNION_ANON;
+} __ABI_PACKED;
+
+/**
+ * @addtogroup Debugfs
+ * @{
+ */
+#define DEBUGFS_S_ISDIR (1 << 9)
+#define DEBUGFS_S_IRUSR (1 << 8)
+#define DEBUGFS_S_IWUSR (1 << 7)
+/** @} */
+
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_RESET
+ * @brief reset an IP block
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_reset_request
+ * * Response Payload: N/A
+ */
+
+/**
+ * @ingroup Reset
+ */
+enum mrq_reset_commands {
+ CMD_RESET_ASSERT = 1,
+ CMD_RESET_DEASSERT = 2,
+ CMD_RESET_MODULE = 3,
+ CMD_RESET_MAX, /* not part of ABI and subject to change */
+};
+
+/**
+ * @ingroup Reset
+ * @brief request with MRQ_RESET
+ *
+ * Used by the sender of an #MRQ_RESET message to request BPMP to
+ * assert or or deassert a given reset line.
+ */
+struct mrq_reset_request {
+ /** @brief reset action to perform (@enum mrq_reset_commands) */
+ uint32_t cmd;
+ /** @brief id of the reset to affected */
+ uint32_t reset_id;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_I2C
+ * @brief issue an i2c transaction
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_i2c_request
+ * * Response Payload: @ref mrq_i2c_response
+ */
+
+/**
+ * @addtogroup I2C
+ * @{
+ */
+#define TEGRA_I2C_IPC_MAX_IN_BUF_SIZE (MSG_DATA_MIN_SZ - 12)
+#define TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE (MSG_DATA_MIN_SZ - 4)
+/** @} */
+
+/**
+ * @ingroup I2C
+ * @name Serial I2C flags
+ * Use these flags with serial_i2c_request::flags
+ * @{
+ */
+#define SERIALI2C_TEN 0x0010
+#define SERIALI2C_RD 0x0001
+#define SERIALI2C_STOP 0x8000
+#define SERIALI2C_NOSTART 0x4000
+#define SERIALI2C_REV_DIR_ADDR 0x2000
+#define SERIALI2C_IGNORE_NAK 0x1000
+#define SERIALI2C_NO_RD_ACK 0x0800
+#define SERIALI2C_RECV_LEN 0x0400
+/** @} */
+/** @ingroup I2C */
+enum {
+ CMD_I2C_XFER = 1
+};
+
+/**
+ * @ingroup I2C
+ * @brief serializable i2c request
+ *
+ * Instances of this structure are packed (little-endian) into
+ * cmd_i2c_xfer_request::data_buf. Each instance represents a single
+ * transaction (or a portion of a transaction with repeated starts) on
+ * an i2c bus.
+ *
+ * Because these structures are packed, some instances are likely to
+ * be misaligned. Additionally because #data is variable length, it is
+ * not possible to iterate through a serialized list of these
+ * structures without inspecting #len in each instance. It may be
+ * easier to serialize or deserialize cmd_i2c_xfer_request::data_buf
+ * manually rather than using this structure definition.
+*/
+struct serial_i2c_request {
+ /** @brief I2C slave address */
+ uint16_t addr;
+ /** @brief bitmask of SERIALI2C_ flags */
+ uint16_t flags;
+ /** @brief length of I2C transaction in bytes */
+ uint16_t len;
+ /** @brief for write transactions only, #len bytes of data */
+ uint8_t data[];
+} __ABI_PACKED;
+
+/**
+ * @ingroup I2C
+ * @brief trigger one or more i2c transactions
+ */
+struct cmd_i2c_xfer_request {
+ /** @brief valid bus number from mach-t186/i2c-t186.h*/
+ uint32_t bus_id;
+
+ /** @brief count of valid bytes in #data_buf*/
+ uint32_t data_size;
+
+ /** @brief serialized packed instances of @ref serial_i2c_request*/
+ uint8_t data_buf[TEGRA_I2C_IPC_MAX_IN_BUF_SIZE];
+} __ABI_PACKED;
+
+/**
+ * @ingroup I2C
+ * @brief container for data read from the i2c bus
+ *
+ * Processing an cmd_i2c_xfer_request::data_buf causes BPMP to execute
+ * zero or more I2C reads. The data read from the bus is serialized
+ * into #data_buf.
+ */
+struct cmd_i2c_xfer_response {
+ /** @brief count of valid bytes in #data_buf*/
+ uint32_t data_size;
+ /** @brief i2c read data */
+ uint8_t data_buf[TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE];
+} __ABI_PACKED;
+
+/**
+ * @ingroup I2C
+ * @brief request with #MRQ_I2C
+ */
+struct mrq_i2c_request {
+ /** @brief always CMD_I2C_XFER (i.e. 1) */
+ uint32_t cmd;
+ /** @brief parameters of the transfer request */
+ struct cmd_i2c_xfer_request xfer;
+} __ABI_PACKED;
+
+/**
+ * @ingroup I2C
+ * @brief response to #MRQ_I2C
+ */
+struct mrq_i2c_response {
+ struct cmd_i2c_xfer_response xfer;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_CLK
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_clk_request
+ * * Response Payload: @ref mrq_clk_response
+ * @addtogroup Clocks
+ * @{
+ */
+
+/**
+ * @name MRQ_CLK sub-commands
+ * @{
+ */
+enum {
+ CMD_CLK_GET_RATE = 1,
+ CMD_CLK_SET_RATE = 2,
+ CMD_CLK_ROUND_RATE = 3,
+ CMD_CLK_GET_PARENT = 4,
+ CMD_CLK_SET_PARENT = 5,
+ CMD_CLK_IS_ENABLED = 6,
+ CMD_CLK_ENABLE = 7,
+ CMD_CLK_DISABLE = 8,
+ CMD_CLK_GET_ALL_INFO = 14,
+ CMD_CLK_GET_MAX_CLK_ID = 15,
+ CMD_CLK_MAX,
+};
+/** @} */
+
+#define MRQ_CLK_NAME_MAXLEN 40
+#define MRQ_CLK_MAX_PARENTS 16
+
+/** @private */
+struct cmd_clk_get_rate_request {
+ EMPTY
+} __ABI_PACKED;
+
+struct cmd_clk_get_rate_response {
+ int64_t rate;
+} __ABI_PACKED;
+
+struct cmd_clk_set_rate_request {
+ int32_t unused;
+ int64_t rate;
+} __ABI_PACKED;
+
+struct cmd_clk_set_rate_response {
+ int64_t rate;
+} __ABI_PACKED;
+
+struct cmd_clk_round_rate_request {
+ int32_t unused;
+ int64_t rate;
+} __ABI_PACKED;
+
+struct cmd_clk_round_rate_response {
+ int64_t rate;
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_get_parent_request {
+ EMPTY
+} __ABI_PACKED;
+
+struct cmd_clk_get_parent_response {
+ uint32_t parent_id;
+} __ABI_PACKED;
+
+struct cmd_clk_set_parent_request {
+ uint32_t parent_id;
+} __ABI_PACKED;
+
+struct cmd_clk_set_parent_response {
+ uint32_t parent_id;
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_is_enabled_request {
+ EMPTY
+} __ABI_PACKED;
+
+struct cmd_clk_is_enabled_response {
+ int32_t state;
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_enable_request {
+ EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_enable_response {
+ EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_disable_request {
+ EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_disable_response {
+ EMPTY
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_get_all_info_request {
+ EMPTY
+} __ABI_PACKED;
+
+struct cmd_clk_get_all_info_response {
+ uint32_t flags;
+ uint32_t parent;
+ uint32_t parents[MRQ_CLK_MAX_PARENTS];
+ uint8_t num_parents;
+ uint8_t name[MRQ_CLK_NAME_MAXLEN];
+} __ABI_PACKED;
+
+/** @private */
+struct cmd_clk_get_max_clk_id_request {
+ EMPTY
+} __ABI_PACKED;
+
+struct cmd_clk_get_max_clk_id_response {
+ uint32_t max_id;
+} __ABI_PACKED;
+/** @} */
+
+/**
+ * @ingroup Clocks
+ * @brief request with #MRQ_CLK
+ *
+ * Used by the sender of an #MRQ_CLK message to control clocks. The
+ * clk_request is split into several sub-commands. Some sub-commands
+ * require no additional data. Others have a sub-command specific
+ * payload
+ *
+ * |sub-command |payload |
+ * |----------------------------|-----------------------|
+ * |CMD_CLK_GET_RATE |- |
+ * |CMD_CLK_SET_RATE |clk_set_rate |
+ * |CMD_CLK_ROUND_RATE |clk_round_rate |
+ * |CMD_CLK_GET_PARENT |- |
+ * |CMD_CLK_SET_PARENT |clk_set_parent |
+ * |CMD_CLK_IS_ENABLED |- |
+ * |CMD_CLK_ENABLE |- |
+ * |CMD_CLK_DISABLE |- |
+ * |CMD_CLK_GET_ALL_INFO |- |
+ * |CMD_CLK_GET_MAX_CLK_ID |- |
+ *
+ */
+
+struct mrq_clk_request {
+ /** @brief sub-command and clock id concatenated to 32-bit word.
+ * - bits[31..24] is the sub-cmd.
+ * - bits[23..0] is the clock id
+ */
+ uint32_t cmd_and_id;
+
+ union {
+ /** @private */
+ struct cmd_clk_get_rate_request clk_get_rate;
+ struct cmd_clk_set_rate_request clk_set_rate;
+ struct cmd_clk_round_rate_request clk_round_rate;
+ /** @private */
+ struct cmd_clk_get_parent_request clk_get_parent;
+ struct cmd_clk_set_parent_request clk_set_parent;
+ /** @private */
+ struct cmd_clk_enable_request clk_enable;
+ /** @private */
+ struct cmd_clk_disable_request clk_disable;
+ /** @private */
+ struct cmd_clk_is_enabled_request clk_is_enabled;
+ /** @private */
+ struct cmd_clk_get_all_info_request clk_get_all_info;
+ /** @private */
+ struct cmd_clk_get_max_clk_id_request clk_get_max_clk_id;
+ } __UNION_ANON;
+} __ABI_PACKED;
+
+/**
+ * @ingroup Clocks
+ * @brief response to MRQ_CLK
+ *
+ * Each sub-command supported by @ref mrq_clk_request may return
+ * sub-command-specific data. Some do and some do not as indicated in
+ * the following table
+ *
+ * |sub-command |payload |
+ * |----------------------------|------------------------|
+ * |CMD_CLK_GET_RATE |clk_get_rate |
+ * |CMD_CLK_SET_RATE |clk_set_rate |
+ * |CMD_CLK_ROUND_RATE |clk_round_rate |
+ * |CMD_CLK_GET_PARENT |clk_get_parent |
+ * |CMD_CLK_SET_PARENT |clk_set_parent |
+ * |CMD_CLK_IS_ENABLED |clk_is_enabled |
+ * |CMD_CLK_ENABLE |- |
+ * |CMD_CLK_DISABLE |- |
+ * |CMD_CLK_GET_ALL_INFO |clk_get_all_info |
+ * |CMD_CLK_GET_MAX_CLK_ID |clk_get_max_id |
+ *
+ */
+
+struct mrq_clk_response {
+ union {
+ struct cmd_clk_get_rate_response clk_get_rate;
+ struct cmd_clk_set_rate_response clk_set_rate;
+ struct cmd_clk_round_rate_response clk_round_rate;
+ struct cmd_clk_get_parent_response clk_get_parent;
+ struct cmd_clk_set_parent_response clk_set_parent;
+ /** @private */
+ struct cmd_clk_enable_response clk_enable;
+ /** @private */
+ struct cmd_clk_disable_response clk_disable;
+ struct cmd_clk_is_enabled_response clk_is_enabled;
+ struct cmd_clk_get_all_info_response clk_get_all_info;
+ struct cmd_clk_get_max_clk_id_response clk_get_max_clk_id;
+ } __UNION_ANON;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_QUERY_ABI
+ * @brief check if an MRQ is implemented
+ *
+ * * Platforms: All
+ * * Initiators: Any
+ * * Targets: Any
+ * * Request Payload: @ref mrq_query_abi_request
+ * * Response Payload: @ref mrq_query_abi_response
+ */
+
+/**
+ * @ingroup ABI_info
+ * @brief request with MRQ_QUERY_ABI
+ *
+ * Used by #MRQ_QUERY_ABI call to check if MRQ code #mrq is supported
+ * by the recipient.
+ */
+struct mrq_query_abi_request {
+ /** @brief MRQ code to query */
+ uint32_t mrq;
+} __ABI_PACKED;
+
+/**
+ * @ingroup ABI_info
+ * @brief response to MRQ_QUERY_ABI
+ */
+struct mrq_query_abi_response {
+ /** @brief 0 if queried MRQ is supported. Else, -#BPMP_ENODEV */
+ int32_t status;
+} __ABI_PACKED;
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_PG_READ_STATE
+ * @brief read the power-gating state of a partition
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_pg_read_state_request
+ * * Response Payload: @ref mrq_pg_read_state_response
+ * @addtogroup Powergating
+ * @{
+ */
+
+/**
+ * @brief request with #MRQ_PG_READ_STATE
+ *
+ * Used by MRQ_PG_READ_STATE call to read the current state of a
+ * partition.
+ */
+struct mrq_pg_read_state_request {
+ /** @brief ID of partition */
+ uint32_t partition_id;
+} __ABI_PACKED;
+
+/**
+ * @brief response to MRQ_PG_READ_STATE
+ * @todo define possible errors.
+ */
+struct mrq_pg_read_state_response {
+ /** @brief read as don't care */
+ uint32_t sram_state;
+ /** @brief state of power partition
+ * * 0 : off
+ * * 1 : on
+ */
+ uint32_t logic_state;
+} __ABI_PACKED;
+
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_PG_UPDATE_STATE
+ * @brief modify the power-gating state of a partition
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_pg_update_state_request
+ * * Response Payload: N/A
+ * @addtogroup Powergating
+ * @{
+ */
+
+/**
+ * @brief request with mrq_pg_update_state_request
+ *
+ * Used by #MRQ_PG_UPDATE_STATE call to request BPMP to change the
+ * state of a power partition #partition_id.
+ */
+struct mrq_pg_update_state_request {
+ /** @brief ID of partition */
+ uint32_t partition_id;
+ /** @brief secondary control of power partition
+ * @details Ignored by many versions of the BPMP
+ * firmware. For maximum compatibility, set the value
+ * according to @logic_state
+ * * 0x1: power ON partition (@ref logic_state == 0x3)
+ * * 0x3: power OFF partition (@ref logic_state == 0x1)
+ */
+ uint32_t sram_state;
+ /** @brief controls state of power partition, legal values are
+ * * 0x1 : power OFF partition
+ * * 0x3 : power ON partition
+ */
+ uint32_t logic_state;
+ /** @brief change state of clocks of the power partition, legal values
+ * * 0x0 : do not change clock state
+ * * 0x1 : disable partition clocks (only applicable when
+ * @ref logic_state == 0x1)
+ * * 0x3 : enable partition clocks (only applicable when
+ * @ref logic_state == 0x3)
+ */
+ uint32_t clock_state;
+} __ABI_PACKED;
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_THERMAL
+ * @brief interact with BPMP thermal framework
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: Any
+ * * Request Payload: TODO
+ * * Response Payload: TODO
+ *
+ * @addtogroup Thermal
+ *
+ * The BPMP firmware includes a thermal framework. Drivers within the
+ * bpmp firmware register with the framework to provide thermal
+ * zones. Each thermal zone corresponds to an entity whose temperature
+ * can be measured. The framework also has a notion of trip points. A
+ * trip point consists of a thermal zone id, a temperature, and a
+ * callback routine. The framework invokes the callback when the zone
+ * hits the indicated temperature. The BPMP firmware uses this thermal
+ * framework interally to implement various temperature-dependent
+ * functions.
+ *
+ * Software on the CPU can use #MRQ_THERMAL (with payload @ref
+ * mrq_thermal_host_to_bpmp_request) to interact with the BPMP thermal
+ * framework. The CPU must It can query the number of supported zones,
+ * query zone temperatures, and set trip points.
+ *
+ * When a trip point set by the CPU gets crossed, BPMP firmware issues
+ * an IPC to the CPU having mrq_request::mrq = #MRQ_THERMAL and a
+ * payload of @ref mrq_thermal_bpmp_to_host_request.
+ * @{
+ */
+enum mrq_thermal_host_to_bpmp_cmd {
+ /**
+ * @brief Check whether the BPMP driver supports the specified
+ * request type.
+ *
+ * Host needs to supply request parameters.
+ *
+ * mrq_response::err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_THERMAL_QUERY_ABI = 0,
+
+ /**
+ * @brief Get the current temperature of the specified zone.
+ *
+ * Host needs to supply request parameters.
+ *
+ * mrq_response::err is
+ * * 0: Temperature query succeeded.
+ * * -#BPMP_EINVAL: Invalid request parameters.
+ * * -#BPMP_ENOENT: No driver registered for thermal zone..
+ * * -#BPMP_EFAULT: Problem reading temperature measurement.
+ */
+ CMD_THERMAL_GET_TEMP = 1,
+
+ /**
+ * @brief Enable or disable and set the lower and upper
+ * thermal limits for a thermal trip point. Each zone has
+ * one trip point.
+ *
+ * Host needs to supply request parameters. Once the
+ * temperature hits a trip point, the BPMP will send a message
+ * to the CPU having MRQ=MRQ_THERMAL and
+ * type=CMD_THERMAL_HOST_TRIP_REACHED
+ *
+ * mrq_response::err is
+ * * 0: Trip successfully set.
+ * * -#BPMP_EINVAL: Invalid request parameters.
+ * * -#BPMP_ENOENT: No driver registered for thermal zone.
+ * * -#BPMP_EFAULT: Problem setting trip point.
+ */
+ CMD_THERMAL_SET_TRIP = 2,
+
+ /**
+ * @brief Get the number of supported thermal zones.
+ *
+ * No request parameters required.
+ *
+ * mrq_response::err is always 0, indicating success.
+ */
+ CMD_THERMAL_GET_NUM_ZONES = 3,
+
+ /** @brief: number of supported host-to-bpmp commands. May
+ * increase in future
+ */
+ CMD_THERMAL_HOST_TO_BPMP_NUM
+};
+
+enum mrq_thermal_bpmp_to_host_cmd {
+ /**
+ * @brief Indication that the temperature for a zone has
+ * exceeded the range indicated in the thermal trip point
+ * for the zone.
+ *
+ * BPMP needs to supply request parameters. Host only needs to
+ * acknowledge.
+ */
+ CMD_THERMAL_HOST_TRIP_REACHED = 100,
+
+ /** @brief: number of supported bpmp-to-host commands. May
+ * increase in future
+ */
+ CMD_THERMAL_BPMP_TO_HOST_NUM
+};
+
+/*
+ * Host->BPMP request data for request type CMD_THERMAL_QUERY_ABI
+ *
+ * zone: Request type for which to check existence.
+ */
+struct cmd_thermal_query_abi_request {
+ uint32_t type;
+} __ABI_PACKED;
+
+/*
+ * Host->BPMP request data for request type CMD_THERMAL_GET_TEMP
+ *
+ * zone: Number of thermal zone.
+ */
+struct cmd_thermal_get_temp_request {
+ uint32_t zone;
+} __ABI_PACKED;
+
+/*
+ * BPMP->Host reply data for request CMD_THERMAL_GET_TEMP
+ *
+ * error: 0 if request succeeded.
+ * -BPMP_EINVAL if request parameters were invalid.
+ * -BPMP_ENOENT if no driver was registered for the specified thermal zone.
+ * -BPMP_EFAULT for other thermal zone driver errors.
+ * temp: Current temperature in millicelsius.
+ */
+struct cmd_thermal_get_temp_response {
+ int32_t temp;
+} __ABI_PACKED;
+
+/*
+ * Host->BPMP request data for request type CMD_THERMAL_SET_TRIP
+ *
+ * zone: Number of thermal zone.
+ * low: Temperature of lower trip point in millicelsius
+ * high: Temperature of upper trip point in millicelsius
+ * enabled: 1 to enable trip point, 0 to disable trip point
+ */
+struct cmd_thermal_set_trip_request {
+ uint32_t zone;
+ int32_t low;
+ int32_t high;
+ uint32_t enabled;
+} __ABI_PACKED;
+
+/*
+ * BPMP->Host request data for request type CMD_THERMAL_HOST_TRIP_REACHED
+ *
+ * zone: Number of thermal zone where trip point was reached.
+ */
+struct cmd_thermal_host_trip_reached_request {
+ uint32_t zone;
+} __ABI_PACKED;
+
+/*
+ * BPMP->Host reply data for request type CMD_THERMAL_GET_NUM_ZONES
+ *
+ * num: Number of supported thermal zones. The thermal zones are indexed
+ * starting from zero.
+ */
+struct cmd_thermal_get_num_zones_response {
+ uint32_t num;
+} __ABI_PACKED;
+
+/*
+ * Host->BPMP request data.
+ *
+ * Reply type is union mrq_thermal_bpmp_to_host_response.
+ *
+ * type: Type of request. Values listed in enum mrq_thermal_type.
+ * data: Request type specific parameters.
+ */
+struct mrq_thermal_host_to_bpmp_request {
+ uint32_t type;
+ union {
+ struct cmd_thermal_query_abi_request query_abi;
+ struct cmd_thermal_get_temp_request get_temp;
+ struct cmd_thermal_set_trip_request set_trip;
+ } __UNION_ANON;
+} __ABI_PACKED;
+
+/*
+ * BPMP->Host request data.
+ *
+ * type: Type of request. Values listed in enum mrq_thermal_type.
+ * data: Request type specific parameters.
+ */
+struct mrq_thermal_bpmp_to_host_request {
+ uint32_t type;
+ union {
+ struct cmd_thermal_host_trip_reached_request host_trip_reached;
+ } __UNION_ANON;
+} __ABI_PACKED;
+
+/*
+ * Data in reply to a Host->BPMP request.
+ */
+union mrq_thermal_bpmp_to_host_response {
+ struct cmd_thermal_get_temp_response get_temp;
+ struct cmd_thermal_get_num_zones_response get_num_zones;
+} __ABI_PACKED;
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_CPU_VHINT
+ * @brief Query CPU voltage hint data
+ *
+ * * Platforms: T186
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_cpu_vhint_request
+ * * Response Payload: N/A
+ *
+ * @addtogroup Vhint CPU Voltage hint
+ * @{
+ */
+
+/**
+ * @brief request with #MRQ_CPU_VHINT
+ *
+ * Used by #MRQ_CPU_VHINT call by CCPLEX to retrieve voltage hint data
+ * from BPMP to memory space pointed by #addr. CCPLEX is responsible
+ * to allocate sizeof(cpu_vhint_data) sized block of memory and
+ * appropriately map it for BPMP before sending the request.
+ */
+struct mrq_cpu_vhint_request {
+ /** @brief IOVA address for the #cpu_vhint_data */
+ uint32_t addr; /* struct cpu_vhint_data * */
+ /** @brief ID of the cluster whose data is requested */
+ uint32_t cluster_id; /* enum cluster_id */
+} __ABI_PACKED;
+
+/**
+ * @brief description of the CPU v/f relation
+ *
+ * Used by #MRQ_CPU_VHINT call to carry data pointed by #addr of
+ * struct mrq_cpu_vhint_request
+ */
+struct cpu_vhint_data {
+ uint32_t ref_clk_hz; /**< reference frequency in Hz */
+ uint16_t pdiv; /**< post divider value */
+ uint16_t mdiv; /**< input divider value */
+ uint16_t ndiv_max; /**< fMAX expressed with max NDIV value */
+ /** table of ndiv values as a function of vINDEX (voltage index) */
+ uint16_t ndiv[80];
+ /** minimum allowed NDIV value */
+ uint16_t ndiv_min;
+ /** minimum allowed voltage hint value (as in vINDEX) */
+ uint16_t vfloor;
+ /** maximum allowed voltage hint value (as in vINDEX) */
+ uint16_t vceil;
+ /** post-multiplier for vindex value */
+ uint16_t vindex_mult;
+ /** post-divider for vindex value */
+ uint16_t vindex_div;
+ /** reserved for future use */
+ uint16_t reserved[328];
+} __ABI_PACKED;
+
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_ABI_RATCHET
+ * @brief ABI ratchet value query
+ *
+ * * Platforms: T186
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_abi_ratchet_request
+ * * Response Payload: @ref mrq_abi_ratchet_response
+ * @addtogroup ABI_info
+ * @{
+ */
+
+/**
+ * @brief an ABI compatibility mechanism
+ *
+ * BPMP_ABI_RATCHET_VALUE may increase for various reasons in a future
+ * revision of this header file.
+ * 1. That future revision deprecates some MRQ
+ * 2. That future revision introduces a breaking change to an existing
+ * MRQ or
+ * 3. A bug is discovered in an existing implementation of the BPMP-FW
+ * (or possibly one of its clients) which warrants deprecating that
+ * implementation.
+ */
+#define BPMP_ABI_RATCHET_VALUE 3
+
+/**
+ * @brief request with #MRQ_ABI_RATCHET.
+ *
+ * #ratchet should be #BPMP_ABI_RATCHET_VALUE from the ABI header
+ * against which the requester was compiled.
+ *
+ * If ratchet is less than BPMP's #BPMP_ABI_RATCHET_VALUE, BPMP may
+ * reply with mrq_response::err = -#BPMP_ERANGE to indicate that
+ * BPMP-FW cannot interoperate correctly with the requester. Requester
+ * should cease further communication with BPMP.
+ *
+ * Otherwise, err shall be 0.
+ */
+struct mrq_abi_ratchet_request {
+ /** @brief requester's ratchet value */
+ uint16_t ratchet;
+};
+
+/**
+ * @brief response to #MRQ_ABI_RATCHET
+ *
+ * #ratchet shall be #BPMP_ABI_RATCHET_VALUE from the ABI header
+ * against which BPMP firwmare was compiled.
+ *
+ * If #ratchet is less than the requester's #BPMP_ABI_RATCHET_VALUE,
+ * the requster must either interoperate with BPMP according to an ABI
+ * header version with BPMP_ABI_RATCHET_VALUE = ratchet or cease
+ * communication with BPMP.
+ *
+ * If mrq_response::err is 0 and ratchet is greater than or equal to the
+ * requester's BPMP_ABI_RATCHET_VALUE, the requester should continue
+ * normal operation.
+ */
+struct mrq_abi_ratchet_response {
+ /** @brief BPMP's ratchet value */
+ uint16_t ratchet;
+};
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_EMC_DVFS_LATENCY
+ * @brief query frequency dependent EMC DVFS latency
+ *
+ * * Platforms: T186
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: N/A
+ * * Response Payload: @ref mrq_emc_dvfs_latency_response
+ * @addtogroup EMC
+ * @{
+ */
+
+/**
+ * @brief used by @ref mrq_emc_dvfs_latency_response
+ */
+struct emc_dvfs_latency {
+ /** @brief EMC frequency in kHz */
+ uint32_t freq;
+ /** @brief EMC DVFS latency in nanoseconds */
+ uint32_t latency;
+} __ABI_PACKED;
+
+#define EMC_DVFS_LATENCY_MAX_SIZE 14
+/**
+ * @brief response to #MRQ_EMC_DVFS_LATENCY
+ */
+struct mrq_emc_dvfs_latency_response {
+ /** @brief the number valid entries in #pairs */
+ uint32_t num_pairs;
+ /** @brief EMC <frequency, latency> information */
+ struct emc_dvfs_latency pairs[EMC_DVFS_LATENCY_MAX_SIZE];
+} __ABI_PACKED;
+
+/** @} */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_TRACE_ITER
+ * @brief manage the trace iterator
+ *
+ * * Platforms: All
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: N/A
+ * * Response Payload: @ref mrq_trace_iter_request
+ * @addtogroup Trace
+ * @{
+ */
+enum {
+ /** @brief (re)start the tracing now. Ignore older events */
+ TRACE_ITER_INIT = 0,
+ /** @brief clobber all events in the trace buffer */
+ TRACE_ITER_CLEAN = 1
+};
+
+/**
+ * @brief request with #MRQ_TRACE_ITER
+ */
+struct mrq_trace_iter_request {
+ /** @brief TRACE_ITER_INIT or TRACE_ITER_CLEAN */
+ uint32_t cmd;
+} __ABI_PACKED;
+
+/** @} */
+
+/*
+ * 4. Enumerations
+ */
+
+/*
+ * 4.1 CPU enumerations
+ *
+ * See <mach-t186/system-t186.h>
+ *
+ * 4.2 CPU Cluster enumerations
+ *
+ * See <mach-t186/system-t186.h>
+ *
+ * 4.3 System low power state enumerations
+ *
+ * See <mach-t186/system-t186.h>
+ */
+
+/*
+ * 4.4 Clock enumerations
+ *
+ * For clock enumerations, see <mach-t186/clk-t186.h>
+ */
+
+/*
+ * 4.5 Reset enumerations
+ *
+ * For reset enumerations, see <mach-t186/reset-t186.h>
+ */
+
+/*
+ * 4.6 Thermal sensor enumerations
+ *
+ * For thermal sensor enumerations, see <mach-t186/thermal-t186.h>
+ */
+
+/**
+ * @defgroup Error_Codes
+ * Negative values for mrq_response::err generally indicate some
+ * error. The ABI defines the following error codes. Negating these
+ * defines is an exercise left to the user.
+ * @{
+ */
+/** @brief No such file or directory */
+#define BPMP_ENOENT 2
+/** @brief No MRQ handler */
+#define BPMP_ENOHANDLER 3
+/** @brief I/O error */
+#define BPMP_EIO 5
+/** @brief Bad sub-MRQ command */
+#define BPMP_EBADCMD 6
+/** @brief Not enough memory */
+#define BPMP_ENOMEM 12
+/** @brief Permission denied */
+#define BPMP_EACCES 13
+/** @brief Bad address */
+#define BPMP_EFAULT 14
+/** @brief No such device */
+#define BPMP_ENODEV 19
+/** @brief Argument is a directory */
+#define BPMP_EISDIR 21
+/** @brief Invalid argument */
+#define BPMP_EINVAL 22
+/** @brief Timeout during operation */
+#define BPMP_ETIMEDOUT 23
+/** @brief Out of range */
+#define BPMP_ERANGE 34
+/** @} */
+/** @} */
+#endif
diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h
new file mode 100644
index 000000000000..13dcd44e91bb
--- /dev/null
+++ b/include/soc/tegra/bpmp.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __SOC_TEGRA_BPMP_H
+#define __SOC_TEGRA_BPMP_H
+
+#include <linux/mailbox_client.h>
+#include <linux/reset-controller.h>
+#include <linux/semaphore.h>
+#include <linux/types.h>
+
+#include <soc/tegra/bpmp-abi.h>
+
+struct tegra_bpmp_clk;
+
+struct tegra_bpmp_soc {
+ struct {
+ struct {
+ unsigned int offset;
+ unsigned int count;
+ unsigned int timeout;
+ } cpu_tx, thread, cpu_rx;
+ } channels;
+ unsigned int num_resets;
+};
+
+struct tegra_bpmp_mb_data {
+ u32 code;
+ u32 flags;
+ u8 data[MSG_DATA_MIN_SZ];
+} __packed;
+
+struct tegra_bpmp_channel {
+ struct tegra_bpmp *bpmp;
+ struct tegra_bpmp_mb_data *ib;
+ struct tegra_bpmp_mb_data *ob;
+ struct completion completion;
+ struct tegra_ivc *ivc;
+};
+
+typedef void (*tegra_bpmp_mrq_handler_t)(unsigned int mrq,
+ struct tegra_bpmp_channel *channel,
+ void *data);
+
+struct tegra_bpmp_mrq {
+ struct list_head list;
+ unsigned int mrq;
+ tegra_bpmp_mrq_handler_t handler;
+ void *data;
+};
+
+struct tegra_bpmp {
+ const struct tegra_bpmp_soc *soc;
+ struct device *dev;
+
+ struct {
+ struct gen_pool *pool;
+ dma_addr_t phys;
+ void *virt;
+ } tx, rx;
+
+ struct {
+ struct mbox_client client;
+ struct mbox_chan *channel;
+ } mbox;
+
+ struct tegra_bpmp_channel *channels;
+ unsigned int num_channels;
+
+ struct {
+ unsigned long *allocated;
+ unsigned long *busy;
+ unsigned int count;
+ struct semaphore lock;
+ } threaded;
+
+ struct list_head mrqs;
+ spinlock_t lock;
+
+ struct tegra_bpmp_clk **clocks;
+ unsigned int num_clocks;
+
+ struct reset_controller_dev rstc;
+};
+
+struct tegra_bpmp *tegra_bpmp_get(struct device *dev);
+void tegra_bpmp_put(struct tegra_bpmp *bpmp);
+
+struct tegra_bpmp_message {
+ unsigned int mrq;
+
+ struct {
+ const void *data;
+ size_t size;
+ } tx;
+
+ struct {
+ void *data;
+ size_t size;
+ } rx;
+};
+
+int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
+ struct tegra_bpmp_message *msg);
+int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
+ struct tegra_bpmp_message *msg);
+
+int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
+ tegra_bpmp_mrq_handler_t handler, void *data);
+void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
+ void *data);
+
+#if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP)
+int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp);
+#else
+static inline int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp)
+{
+ return 0;
+}
+#endif
+
+#if IS_ENABLED(CONFIG_RESET_TEGRA_BPMP)
+int tegra_bpmp_init_resets(struct tegra_bpmp *bpmp);
+#else
+static inline int tegra_bpmp_init_resets(struct tegra_bpmp *bpmp)
+{
+ return 0;
+}
+#endif
+
+#endif /* __SOC_TEGRA_BPMP_H */
diff --git a/include/soc/tegra/ivc.h b/include/soc/tegra/ivc.h
new file mode 100644
index 000000000000..b13cc43ad9d8
--- /dev/null
+++ b/include/soc/tegra/ivc.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __TEGRA_IVC_H
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/types.h>
+
+struct tegra_ivc_header;
+
+struct tegra_ivc {
+ struct device *peer;
+
+ struct {
+ struct tegra_ivc_header *channel;
+ unsigned int position;
+ dma_addr_t phys;
+ } rx, tx;
+
+ void (*notify)(struct tegra_ivc *ivc, void *data);
+ void *notify_data;
+
+ unsigned int num_frames;
+ size_t frame_size;
+};
+
+/**
+ * tegra_ivc_read_get_next_frame - Peek at the next frame to receive
+ * @ivc pointer of the IVC channel
+ *
+ * Peek at the next frame to be received, without removing it from
+ * the queue.
+ *
+ * Returns a pointer to the frame, or an error encoded pointer.
+ */
+void *tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_read_advance - Advance the read queue
+ * @ivc pointer of the IVC channel
+ *
+ * Advance the read queue
+ *
+ * Returns 0, or a negative error value if failed.
+ */
+int tegra_ivc_read_advance(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_write_get_next_frame - Poke at the next frame to transmit
+ * @ivc pointer of the IVC channel
+ *
+ * Get access to the next frame.
+ *
+ * Returns a pointer to the frame, or an error encoded pointer.
+ */
+void *tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_write_advance - Advance the write queue
+ * @ivc pointer of the IVC channel
+ *
+ * Advance the write queue
+ *
+ * Returns 0, or a negative error value if failed.
+ */
+int tegra_ivc_write_advance(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_notified - handle internal messages
+ * @ivc pointer of the IVC channel
+ *
+ * This function must be called following every notification.
+ *
+ * Returns 0 if the channel is ready for communication, or -EAGAIN if a channel
+ * reset is in progress.
+ */
+int tegra_ivc_notified(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_reset - initiates a reset of the shared memory state
+ * @ivc pointer of the IVC channel
+ *
+ * This function must be called after a channel is reserved before it is used
+ * for communication. The channel will be ready for use when a subsequent call
+ * to notify the remote of the channel reset.
+ */
+void tegra_ivc_reset(struct tegra_ivc *ivc);
+
+size_t tegra_ivc_align(size_t size);
+unsigned tegra_ivc_total_queue_size(unsigned queue_size);
+int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx,
+ dma_addr_t rx_phys, void *tx, dma_addr_t tx_phys,
+ unsigned int num_frames, size_t frame_size,
+ void (*notify)(struct tegra_ivc *ivc, void *data),
+ void *data);
+void tegra_ivc_cleanup(struct tegra_ivc *ivc);
+
+#endif /* __TEGRA_IVC_H */
diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h
index e9e53473a63e..2f271d1b9cea 100644
--- a/include/soc/tegra/pmc.h
+++ b/include/soc/tegra/pmc.h
@@ -76,37 +76,73 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid);
#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D
-#define TEGRA_IO_RAIL_CSIA 0
-#define TEGRA_IO_RAIL_CSIB 1
-#define TEGRA_IO_RAIL_DSI 2
-#define TEGRA_IO_RAIL_MIPI_BIAS 3
-#define TEGRA_IO_RAIL_PEX_BIAS 4
-#define TEGRA_IO_RAIL_PEX_CLK1 5
-#define TEGRA_IO_RAIL_PEX_CLK2 6
-#define TEGRA_IO_RAIL_USB0 9
-#define TEGRA_IO_RAIL_USB1 10
-#define TEGRA_IO_RAIL_USB2 11
-#define TEGRA_IO_RAIL_USB_BIAS 12
-#define TEGRA_IO_RAIL_NAND 13
-#define TEGRA_IO_RAIL_UART 14
-#define TEGRA_IO_RAIL_BB 15
-#define TEGRA_IO_RAIL_AUDIO 17
-#define TEGRA_IO_RAIL_HSIC 19
-#define TEGRA_IO_RAIL_COMP 22
-#define TEGRA_IO_RAIL_HDMI 28
-#define TEGRA_IO_RAIL_PEX_CNTRL 32
-#define TEGRA_IO_RAIL_SDMMC1 33
-#define TEGRA_IO_RAIL_SDMMC3 34
-#define TEGRA_IO_RAIL_SDMMC4 35
-#define TEGRA_IO_RAIL_CAM 36
-#define TEGRA_IO_RAIL_RES 37
-#define TEGRA_IO_RAIL_HV 38
-#define TEGRA_IO_RAIL_DSIB 39
-#define TEGRA_IO_RAIL_DSIC 40
-#define TEGRA_IO_RAIL_DSID 41
-#define TEGRA_IO_RAIL_CSIE 44
-#define TEGRA_IO_RAIL_LVDS 57
-#define TEGRA_IO_RAIL_SYS_DDC 58
+/**
+ * enum tegra_io_pad - I/O pad group identifier
+ *
+ * I/O pins on Tegra SoCs are grouped into so-called I/O pads. Each such pad
+ * can be used to control the common voltage signal level and power state of
+ * the pins of the given pad.
+ */
+enum tegra_io_pad {
+ TEGRA_IO_PAD_AUDIO,
+ TEGRA_IO_PAD_AUDIO_HV,
+ TEGRA_IO_PAD_BB,
+ TEGRA_IO_PAD_CAM,
+ TEGRA_IO_PAD_COMP,
+ TEGRA_IO_PAD_CSIA,
+ TEGRA_IO_PAD_CSIB,
+ TEGRA_IO_PAD_CSIC,
+ TEGRA_IO_PAD_CSID,
+ TEGRA_IO_PAD_CSIE,
+ TEGRA_IO_PAD_CSIF,
+ TEGRA_IO_PAD_DBG,
+ TEGRA_IO_PAD_DEBUG_NONAO,
+ TEGRA_IO_PAD_DMIC,
+ TEGRA_IO_PAD_DP,
+ TEGRA_IO_PAD_DSI,
+ TEGRA_IO_PAD_DSIB,
+ TEGRA_IO_PAD_DSIC,
+ TEGRA_IO_PAD_DSID,
+ TEGRA_IO_PAD_EMMC,
+ TEGRA_IO_PAD_EMMC2,
+ TEGRA_IO_PAD_GPIO,
+ TEGRA_IO_PAD_HDMI,
+ TEGRA_IO_PAD_HSIC,
+ TEGRA_IO_PAD_HV,
+ TEGRA_IO_PAD_LVDS,
+ TEGRA_IO_PAD_MIPI_BIAS,
+ TEGRA_IO_PAD_NAND,
+ TEGRA_IO_PAD_PEX_BIAS,
+ TEGRA_IO_PAD_PEX_CLK1,
+ TEGRA_IO_PAD_PEX_CLK2,
+ TEGRA_IO_PAD_PEX_CNTRL,
+ TEGRA_IO_PAD_SDMMC1,
+ TEGRA_IO_PAD_SDMMC3,
+ TEGRA_IO_PAD_SDMMC4,
+ TEGRA_IO_PAD_SPI,
+ TEGRA_IO_PAD_SPI_HV,
+ TEGRA_IO_PAD_SYS_DDC,
+ TEGRA_IO_PAD_UART,
+ TEGRA_IO_PAD_USB0,
+ TEGRA_IO_PAD_USB1,
+ TEGRA_IO_PAD_USB2,
+ TEGRA_IO_PAD_USB3,
+ TEGRA_IO_PAD_USB_BIAS,
+};
+
+/* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */
+#define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI
+#define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS
+
+/**
+ * enum tegra_io_pad_voltage - voltage level of the I/O pad's source rail
+ * @TEGRA_IO_PAD_1800000UV: 1.8 V
+ * @TEGRA_IO_PAD_3300000UV: 3.3 V
+ */
+enum tegra_io_pad_voltage {
+ TEGRA_IO_PAD_1800000UV,
+ TEGRA_IO_PAD_3300000UV,
+};
#ifdef CONFIG_ARCH_TEGRA
int tegra_powergate_is_powered(unsigned int id);
@@ -118,6 +154,13 @@ int tegra_powergate_remove_clamping(unsigned int id);
int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
struct reset_control *rst);
+int tegra_io_pad_power_enable(enum tegra_io_pad id);
+int tegra_io_pad_power_disable(enum tegra_io_pad id);
+int tegra_io_pad_set_voltage(enum tegra_io_pad id,
+ enum tegra_io_pad_voltage voltage);
+int tegra_io_pad_get_voltage(enum tegra_io_pad id);
+
+/* deprecated, use tegra_io_pad_power_{enable,disable}() instead */
int tegra_io_rail_power_on(unsigned int id);
int tegra_io_rail_power_off(unsigned int id);
#else
@@ -148,6 +191,27 @@ static inline int tegra_powergate_sequence_power_up(unsigned int id,
return -ENOSYS;
}
+static inline int tegra_io_pad_power_enable(enum tegra_io_pad id)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_io_pad_power_disable(enum tegra_io_pad id)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_io_pad_set_voltage(enum tegra_io_pad id,
+ enum tegra_io_pad_voltage voltage)
+{
+ return -ENOSYS;
+}
+
+static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id)
+{
+ return -ENOSYS;
+}
+
static inline int tegra_io_rail_power_on(unsigned int id)
{
return -ENOSYS;
diff --git a/include/trace/events/i2c.h b/include/trace/events/i2c.h
index fe17187df65d..4abb8eab34d3 100644
--- a/include/trace/events/i2c.h
+++ b/include/trace/events/i2c.h
@@ -20,7 +20,7 @@
/*
* drivers/i2c/i2c-core.c
*/
-extern void i2c_transfer_trace_reg(void);
+extern int i2c_transfer_trace_reg(void);
extern void i2c_transfer_trace_unreg(void);
/*
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index e5a2e68b2236..174d1147081b 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -23,6 +23,14 @@
#define LINUX_PCI_REGS_H
/*
+ * Conventional PCI and PCI-X Mode 1 devices have 256 bytes of
+ * configuration space. PCI-X Mode 2 and PCIe devices have 4096 bytes of
+ * configuration space.
+ */
+#define PCI_CFG_SPACE_SIZE 256
+#define PCI_CFG_SPACE_EXP_SIZE 4096
+
+/*
* Under PCI, each device has 256 bytes of configuration address space,
* of which the first 64 bytes are standardized as follows:
*/
diff --git a/include/uapi/rdma/Kbuild b/include/uapi/rdma/Kbuild
index f14ab7ff5fee..82bdf5626859 100644
--- a/include/uapi/rdma/Kbuild
+++ b/include/uapi/rdma/Kbuild
@@ -14,3 +14,5 @@ header-y += mlx5-abi.h
header-y += mthca-abi.h
header-y += nes-abi.h
header-y += ocrdma-abi.h
+header-y += hns-abi.h
+header-y += vmw_pvrdma-abi.h
diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h
index d15e7289d835..587b7360e820 100644
--- a/include/uapi/rdma/hfi/hfi1_user.h
+++ b/include/uapi/rdma/hfi/hfi1_user.h
@@ -75,7 +75,7 @@
* may not be implemented; the user code must deal with this if it
* cares, or it must abort after initialization reports the difference.
*/
-#define HFI1_USER_SWMINOR 2
+#define HFI1_USER_SWMINOR 3
/*
* We will encode the major/minor inside a single 32bit version number.
diff --git a/drivers/infiniband/hw/hns/hns_roce_user.h b/include/uapi/rdma/hns-abi.h
index a28f761a9f65..5d7401963e35 100644
--- a/drivers/infiniband/hw/hns/hns_roce_user.h
+++ b/include/uapi/rdma/hns-abi.h
@@ -30,8 +30,10 @@
* SOFTWARE.
*/
-#ifndef _HNS_ROCE_USER_H
-#define _HNS_ROCE_USER_H
+#ifndef HNS_ABI_USER_H
+#define HNS_ABI_USER_H
+
+#include <linux/types.h>
struct hns_roce_ib_create_cq {
__u64 buf_addr;
@@ -49,5 +51,4 @@ struct hns_roce_ib_create_qp {
struct hns_roce_ib_alloc_ucontext_resp {
__u32 qp_tab_size;
};
-
-#endif /*_HNS_ROCE_USER_H */
+#endif /* HNS_ABI_USER_H */
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h
index 25225ebbc7d5..dfdfe4e92d31 100644
--- a/include/uapi/rdma/ib_user_verbs.h
+++ b/include/uapi/rdma/ib_user_verbs.h
@@ -37,6 +37,7 @@
#define IB_USER_VERBS_H
#include <linux/types.h>
+#include <rdma/ib_verbs.h>
/*
* Increment this value if any changes that break userspace ABI
@@ -93,6 +94,7 @@ enum {
IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE,
IB_USER_VERBS_EX_CMD_CREATE_CQ = IB_USER_VERBS_CMD_CREATE_CQ,
IB_USER_VERBS_EX_CMD_CREATE_QP = IB_USER_VERBS_CMD_CREATE_QP,
+ IB_USER_VERBS_EX_CMD_MODIFY_QP = IB_USER_VERBS_CMD_MODIFY_QP,
IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD,
IB_USER_VERBS_EX_CMD_DESTROY_FLOW,
IB_USER_VERBS_EX_CMD_CREATE_WQ,
@@ -545,6 +547,14 @@ enum {
IB_UVERBS_CREATE_QP_SUP_COMP_MASK = IB_UVERBS_CREATE_QP_MASK_IND_TABLE,
};
+enum {
+ IB_USER_LEGACY_LAST_QP_ATTR_MASK = IB_QP_DEST_QPN
+};
+
+enum {
+ IB_USER_LAST_QP_ATTR_MASK = IB_QP_RATE_LIMIT
+};
+
struct ib_uverbs_ex_create_qp {
__u64 user_handle;
__u32 pd_handle;
@@ -684,9 +694,20 @@ struct ib_uverbs_modify_qp {
__u64 driver_data[0];
};
+struct ib_uverbs_ex_modify_qp {
+ struct ib_uverbs_modify_qp base;
+ __u32 rate_limit;
+ __u32 reserved;
+};
+
struct ib_uverbs_modify_qp_resp {
};
+struct ib_uverbs_ex_modify_qp_resp {
+ __u32 comp_mask;
+ __u32 response_length;
+};
+
struct ib_uverbs_destroy_qp {
__u64 response;
__u32 qp_handle;
@@ -908,6 +929,23 @@ struct ib_uverbs_flow_spec_ipv6 {
struct ib_uverbs_flow_ipv6_filter mask;
};
+struct ib_uverbs_flow_tunnel_filter {
+ __be32 tunnel_id;
+};
+
+struct ib_uverbs_flow_spec_tunnel {
+ union {
+ struct ib_uverbs_flow_spec_hdr hdr;
+ struct {
+ __u32 type;
+ __u16 size;
+ __u16 reserved;
+ };
+ };
+ struct ib_uverbs_flow_tunnel_filter val;
+ struct ib_uverbs_flow_tunnel_filter mask;
+};
+
struct ib_uverbs_flow_attr {
__u32 type;
__u16 size;
diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h
index f5d0f4e83b59..fae6cdaeb56d 100644
--- a/include/uapi/rdma/mlx5-abi.h
+++ b/include/uapi/rdma/mlx5-abi.h
@@ -82,6 +82,7 @@ enum mlx5_ib_alloc_ucontext_resp_mask {
enum mlx5_user_cmds_supp_uhw {
MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE = 1 << 0,
+ MLX5_USER_CMDS_SUPP_UHW_CREATE_AH = 1 << 1,
};
struct mlx5_ib_alloc_ucontext_resp {
@@ -124,18 +125,47 @@ struct mlx5_ib_rss_caps {
__u8 reserved[7];
};
+enum mlx5_ib_cqe_comp_res_format {
+ MLX5_IB_CQE_RES_FORMAT_HASH = 1 << 0,
+ MLX5_IB_CQE_RES_FORMAT_CSUM = 1 << 1,
+ MLX5_IB_CQE_RES_RESERVED = 1 << 2,
+};
+
+struct mlx5_ib_cqe_comp_caps {
+ __u32 max_num;
+ __u32 supported_format; /* enum mlx5_ib_cqe_comp_res_format */
+};
+
+struct mlx5_packet_pacing_caps {
+ __u32 qp_rate_limit_min;
+ __u32 qp_rate_limit_max; /* In kpbs */
+
+ /* Corresponding bit will be set if qp type from
+ * 'enum ib_qp_type' is supported, e.g.
+ * supported_qpts |= 1 << IB_QPT_RAW_PACKET
+ */
+ __u32 supported_qpts;
+ __u32 reserved;
+};
+
struct mlx5_ib_query_device_resp {
__u32 comp_mask;
__u32 response_length;
struct mlx5_ib_tso_caps tso_caps;
struct mlx5_ib_rss_caps rss_caps;
+ struct mlx5_ib_cqe_comp_caps cqe_comp_caps;
+ struct mlx5_packet_pacing_caps packet_pacing_caps;
+ __u32 mlx5_ib_support_multi_pkt_send_wqes;
+ __u32 reserved;
};
struct mlx5_ib_create_cq {
__u64 buf_addr;
__u64 db_addr;
__u32 cqe_size;
- __u32 reserved; /* explicit padding (optional on i386) */
+ __u8 cqe_comp_en;
+ __u8 cqe_comp_res_format;
+ __u16 reserved; /* explicit padding (optional on i386) */
};
struct mlx5_ib_create_cq_resp {
@@ -232,6 +262,12 @@ struct mlx5_ib_create_wq {
__u32 reserved;
};
+struct mlx5_ib_create_ah_resp {
+ __u32 response_length;
+ __u8 dmac[ETH_ALEN];
+ __u8 reserved[6];
+};
+
struct mlx5_ib_create_wq_resp {
__u32 response_length;
__u32 reserved;
diff --git a/include/uapi/rdma/rdma_user_cm.h b/include/uapi/rdma/rdma_user_cm.h
index 01923d463673..d71da36e3cd6 100644
--- a/include/uapi/rdma/rdma_user_cm.h
+++ b/include/uapi/rdma/rdma_user_cm.h
@@ -110,7 +110,7 @@ struct rdma_ucm_bind {
__u32 id;
__u16 addr_size;
__u16 reserved;
- struct sockaddr_storage addr;
+ struct __kernel_sockaddr_storage addr;
};
struct rdma_ucm_resolve_ip {
@@ -126,8 +126,8 @@ struct rdma_ucm_resolve_addr {
__u16 src_size;
__u16 dst_size;
__u32 reserved;
- struct sockaddr_storage src_addr;
- struct sockaddr_storage dst_addr;
+ struct __kernel_sockaddr_storage src_addr;
+ struct __kernel_sockaddr_storage dst_addr;
};
struct rdma_ucm_resolve_route {
@@ -164,8 +164,8 @@ struct rdma_ucm_query_addr_resp {
__u16 pkey;
__u16 src_size;
__u16 dst_size;
- struct sockaddr_storage src_addr;
- struct sockaddr_storage dst_addr;
+ struct __kernel_sockaddr_storage src_addr;
+ struct __kernel_sockaddr_storage dst_addr;
};
struct rdma_ucm_query_path_resp {
@@ -257,7 +257,7 @@ struct rdma_ucm_join_mcast {
__u32 id;
__u16 addr_size;
__u16 join_flags;
- struct sockaddr_storage addr;
+ struct __kernel_sockaddr_storage addr;
};
struct rdma_ucm_get_event {
diff --git a/include/uapi/rdma/vmw_pvrdma-abi.h b/include/uapi/rdma/vmw_pvrdma-abi.h
new file mode 100644
index 000000000000..5016abc9ee97
--- /dev/null
+++ b/include/uapi/rdma/vmw_pvrdma-abi.h
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of EITHER the GNU General Public License
+ * version 2 as published by the Free Software Foundation or the BSD
+ * 2-Clause License. This program is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License version 2 for more details at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program available in the file COPYING in the main
+ * directory of this source tree.
+ *
+ * The BSD 2-Clause License
+ *
+ * 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.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __VMW_PVRDMA_ABI_H__
+#define __VMW_PVRDMA_ABI_H__
+
+#include <linux/types.h>
+
+#define PVRDMA_UVERBS_ABI_VERSION 3 /* ABI Version. */
+#define PVRDMA_UAR_HANDLE_MASK 0x00FFFFFF /* Bottom 24 bits. */
+#define PVRDMA_UAR_QP_OFFSET 0 /* QP doorbell. */
+#define PVRDMA_UAR_QP_SEND BIT(30) /* Send bit. */
+#define PVRDMA_UAR_QP_RECV BIT(31) /* Recv bit. */
+#define PVRDMA_UAR_CQ_OFFSET 4 /* CQ doorbell. */
+#define PVRDMA_UAR_CQ_ARM_SOL BIT(29) /* Arm solicited bit. */
+#define PVRDMA_UAR_CQ_ARM BIT(30) /* Arm bit. */
+#define PVRDMA_UAR_CQ_POLL BIT(31) /* Poll bit. */
+
+enum pvrdma_wr_opcode {
+ PVRDMA_WR_RDMA_WRITE,
+ PVRDMA_WR_RDMA_WRITE_WITH_IMM,
+ PVRDMA_WR_SEND,
+ PVRDMA_WR_SEND_WITH_IMM,
+ PVRDMA_WR_RDMA_READ,
+ PVRDMA_WR_ATOMIC_CMP_AND_SWP,
+ PVRDMA_WR_ATOMIC_FETCH_AND_ADD,
+ PVRDMA_WR_LSO,
+ PVRDMA_WR_SEND_WITH_INV,
+ PVRDMA_WR_RDMA_READ_WITH_INV,
+ PVRDMA_WR_LOCAL_INV,
+ PVRDMA_WR_FAST_REG_MR,
+ PVRDMA_WR_MASKED_ATOMIC_CMP_AND_SWP,
+ PVRDMA_WR_MASKED_ATOMIC_FETCH_AND_ADD,
+ PVRDMA_WR_BIND_MW,
+ PVRDMA_WR_REG_SIG_MR,
+};
+
+enum pvrdma_wc_status {
+ PVRDMA_WC_SUCCESS,
+ PVRDMA_WC_LOC_LEN_ERR,
+ PVRDMA_WC_LOC_QP_OP_ERR,
+ PVRDMA_WC_LOC_EEC_OP_ERR,
+ PVRDMA_WC_LOC_PROT_ERR,
+ PVRDMA_WC_WR_FLUSH_ERR,
+ PVRDMA_WC_MW_BIND_ERR,
+ PVRDMA_WC_BAD_RESP_ERR,
+ PVRDMA_WC_LOC_ACCESS_ERR,
+ PVRDMA_WC_REM_INV_REQ_ERR,
+ PVRDMA_WC_REM_ACCESS_ERR,
+ PVRDMA_WC_REM_OP_ERR,
+ PVRDMA_WC_RETRY_EXC_ERR,
+ PVRDMA_WC_RNR_RETRY_EXC_ERR,
+ PVRDMA_WC_LOC_RDD_VIOL_ERR,
+ PVRDMA_WC_REM_INV_RD_REQ_ERR,
+ PVRDMA_WC_REM_ABORT_ERR,
+ PVRDMA_WC_INV_EECN_ERR,
+ PVRDMA_WC_INV_EEC_STATE_ERR,
+ PVRDMA_WC_FATAL_ERR,
+ PVRDMA_WC_RESP_TIMEOUT_ERR,
+ PVRDMA_WC_GENERAL_ERR,
+};
+
+enum pvrdma_wc_opcode {
+ PVRDMA_WC_SEND,
+ PVRDMA_WC_RDMA_WRITE,
+ PVRDMA_WC_RDMA_READ,
+ PVRDMA_WC_COMP_SWAP,
+ PVRDMA_WC_FETCH_ADD,
+ PVRDMA_WC_BIND_MW,
+ PVRDMA_WC_LSO,
+ PVRDMA_WC_LOCAL_INV,
+ PVRDMA_WC_FAST_REG_MR,
+ PVRDMA_WC_MASKED_COMP_SWAP,
+ PVRDMA_WC_MASKED_FETCH_ADD,
+ PVRDMA_WC_RECV = 1 << 7,
+ PVRDMA_WC_RECV_RDMA_WITH_IMM,
+};
+
+enum pvrdma_wc_flags {
+ PVRDMA_WC_GRH = 1 << 0,
+ PVRDMA_WC_WITH_IMM = 1 << 1,
+ PVRDMA_WC_WITH_INVALIDATE = 1 << 2,
+ PVRDMA_WC_IP_CSUM_OK = 1 << 3,
+ PVRDMA_WC_WITH_SMAC = 1 << 4,
+ PVRDMA_WC_WITH_VLAN = 1 << 5,
+ PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_VLAN,
+};
+
+struct pvrdma_alloc_ucontext_resp {
+ __u32 qp_tab_size;
+ __u32 reserved;
+};
+
+struct pvrdma_alloc_pd_resp {
+ __u32 pdn;
+ __u32 reserved;
+};
+
+struct pvrdma_create_cq {
+ __u64 buf_addr;
+ __u32 buf_size;
+ __u32 reserved;
+};
+
+struct pvrdma_create_cq_resp {
+ __u32 cqn;
+ __u32 reserved;
+};
+
+struct pvrdma_resize_cq {
+ __u64 buf_addr;
+ __u32 buf_size;
+ __u32 reserved;
+};
+
+struct pvrdma_create_srq {
+ __u64 buf_addr;
+};
+
+struct pvrdma_create_srq_resp {
+ __u32 srqn;
+ __u32 reserved;
+};
+
+struct pvrdma_create_qp {
+ __u64 rbuf_addr;
+ __u64 sbuf_addr;
+ __u32 rbuf_size;
+ __u32 sbuf_size;
+ __u64 qp_addr;
+};
+
+/* PVRDMA masked atomic compare and swap */
+struct pvrdma_ex_cmp_swap {
+ __u64 swap_val;
+ __u64 compare_val;
+ __u64 swap_mask;
+ __u64 compare_mask;
+};
+
+/* PVRDMA masked atomic fetch and add */
+struct pvrdma_ex_fetch_add {
+ __u64 add_val;
+ __u64 field_boundary;
+};
+
+/* PVRDMA address vector. */
+struct pvrdma_av {
+ __u32 port_pd;
+ __u32 sl_tclass_flowlabel;
+ __u8 dgid[16];
+ __u8 src_path_bits;
+ __u8 gid_index;
+ __u8 stat_rate;
+ __u8 hop_limit;
+ __u8 dmac[6];
+ __u8 reserved[6];
+};
+
+/* PVRDMA scatter/gather entry */
+struct pvrdma_sge {
+ __u64 addr;
+ __u32 length;
+ __u32 lkey;
+};
+
+/* PVRDMA receive queue work request */
+struct pvrdma_rq_wqe_hdr {
+ __u64 wr_id; /* wr id */
+ __u32 num_sge; /* size of s/g array */
+ __u32 total_len; /* reserved */
+};
+/* Use pvrdma_sge (ib_sge) for receive queue s/g array elements. */
+
+/* PVRDMA send queue work request */
+struct pvrdma_sq_wqe_hdr {
+ __u64 wr_id; /* wr id */
+ __u32 num_sge; /* size of s/g array */
+ __u32 total_len; /* reserved */
+ __u32 opcode; /* operation type */
+ __u32 send_flags; /* wr flags */
+ union {
+ __u32 imm_data;
+ __u32 invalidate_rkey;
+ } ex;
+ __u32 reserved;
+ union {
+ struct {
+ __u64 remote_addr;
+ __u32 rkey;
+ __u8 reserved[4];
+ } rdma;
+ struct {
+ __u64 remote_addr;
+ __u64 compare_add;
+ __u64 swap;
+ __u32 rkey;
+ __u32 reserved;
+ } atomic;
+ struct {
+ __u64 remote_addr;
+ __u32 log_arg_sz;
+ __u32 rkey;
+ union {
+ struct pvrdma_ex_cmp_swap cmp_swap;
+ struct pvrdma_ex_fetch_add fetch_add;
+ } wr_data;
+ } masked_atomics;
+ struct {
+ __u64 iova_start;
+ __u64 pl_pdir_dma;
+ __u32 page_shift;
+ __u32 page_list_len;
+ __u32 length;
+ __u32 access_flags;
+ __u32 rkey;
+ } fast_reg;
+ struct {
+ __u32 remote_qpn;
+ __u32 remote_qkey;
+ struct pvrdma_av av;
+ } ud;
+ } wr;
+};
+/* Use pvrdma_sge (ib_sge) for send queue s/g array elements. */
+
+/* Completion queue element. */
+struct pvrdma_cqe {
+ __u64 wr_id;
+ __u64 qp;
+ __u32 opcode;
+ __u32 status;
+ __u32 byte_len;
+ __u32 imm_data;
+ __u32 src_qp;
+ __u32 wc_flags;
+ __u32 vendor_err;
+ __u16 pkey_index;
+ __u16 slid;
+ __u8 sl;
+ __u8 dlid_path_bits;
+ __u8 port_num;
+ __u8 smac[6];
+ __u8 reserved2[7]; /* Pad to next power of 2 (64). */
+};
+
+#endif /* __VMW_PVRDMA_ABI_H__ */
diff --git a/init/main.c b/init/main.c
index 23c275cca73a..c81c9fa21bc7 100644
--- a/init/main.c
+++ b/init/main.c
@@ -81,6 +81,7 @@
#include <linux/integrity.h>
#include <linux/proc_ns.h>
#include <linux/io.h>
+#include <linux/cache.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -925,14 +926,16 @@ static int try_to_run_init_process(const char *init_filename)
static noinline void __init kernel_init_freeable(void);
-#ifdef CONFIG_DEBUG_RODATA
-static bool rodata_enabled = true;
+#if defined(CONFIG_DEBUG_RODATA) || defined(CONFIG_DEBUG_SET_MODULE_RONX)
+bool rodata_enabled __ro_after_init = true;
static int __init set_debug_rodata(char *str)
{
return strtobool(str, &rodata_enabled);
}
__setup("rodata=", set_debug_rodata);
+#endif
+#ifdef CONFIG_DEBUG_RODATA
static void mark_readonly(void)
{
if (rodata_enabled)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 7bd265f6b098..7c38f8f3d97b 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -3191,7 +3191,7 @@ print_lock_nested_lock_not_held(struct task_struct *curr,
return 0;
}
-static int __lock_is_held(struct lockdep_map *lock);
+static int __lock_is_held(struct lockdep_map *lock, int read);
/*
* This gets called for every mutex_lock*()/spin_lock*() operation.
@@ -3332,7 +3332,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
}
chain_key = iterate_chain_key(chain_key, class_idx);
- if (nest_lock && !__lock_is_held(nest_lock))
+ if (nest_lock && !__lock_is_held(nest_lock, -1))
return print_lock_nested_lock_not_held(curr, hlock, ip);
if (!validate_chain(curr, lock, hlock, chain_head, chain_key))
@@ -3579,7 +3579,7 @@ found_it:
return 1;
}
-static int __lock_is_held(struct lockdep_map *lock)
+static int __lock_is_held(struct lockdep_map *lock, int read)
{
struct task_struct *curr = current;
int i;
@@ -3587,8 +3587,12 @@ static int __lock_is_held(struct lockdep_map *lock)
for (i = 0; i < curr->lockdep_depth; i++) {
struct held_lock *hlock = curr->held_locks + i;
- if (match_held_lock(hlock, lock))
- return 1;
+ if (match_held_lock(hlock, lock)) {
+ if (read == -1 || hlock->read == read)
+ return 1;
+
+ return 0;
+ }
}
return 0;
@@ -3772,7 +3776,7 @@ void lock_release(struct lockdep_map *lock, int nested,
}
EXPORT_SYMBOL_GPL(lock_release);
-int lock_is_held(struct lockdep_map *lock)
+int lock_is_held_type(struct lockdep_map *lock, int read)
{
unsigned long flags;
int ret = 0;
@@ -3784,13 +3788,13 @@ int lock_is_held(struct lockdep_map *lock)
check_flags(flags);
current->lockdep_recursion = 1;
- ret = __lock_is_held(lock);
+ ret = __lock_is_held(lock, read);
current->lockdep_recursion = 0;
raw_local_irq_restore(flags);
return ret;
}
-EXPORT_SYMBOL_GPL(lock_is_held);
+EXPORT_SYMBOL_GPL(lock_is_held_type);
struct pin_cookie lock_pin_lock(struct lockdep_map *lock)
{
diff --git a/kernel/module.c b/kernel/module.c
index 0e54d5bf0097..f7482db0f843 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -313,8 +313,11 @@ struct load_info {
} index;
};
-/* We require a truly strong try_module_get(): 0 means failure due to
- ongoing or failed initialization etc. */
+/*
+ * We require a truly strong try_module_get(): 0 means success.
+ * Otherwise an error is returned due to ongoing or failed
+ * initialization etc.
+ */
static inline int strong_try_module_get(struct module *mod)
{
BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED);
@@ -330,7 +333,7 @@ static inline void add_taint_module(struct module *mod, unsigned flag,
enum lockdep_ok lockdep_ok)
{
add_taint(flag, lockdep_ok);
- mod->taints |= (1U << flag);
+ set_bit(flag, &mod->taints);
}
/*
@@ -1138,24 +1141,13 @@ static inline int module_unload_init(struct module *mod)
static size_t module_flags_taint(struct module *mod, char *buf)
{
size_t l = 0;
+ int i;
+
+ for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
+ if (taint_flags[i].module && test_bit(i, &mod->taints))
+ buf[l++] = taint_flags[i].true;
+ }
- if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
- buf[l++] = 'P';
- if (mod->taints & (1 << TAINT_OOT_MODULE))
- buf[l++] = 'O';
- if (mod->taints & (1 << TAINT_FORCED_MODULE))
- buf[l++] = 'F';
- if (mod->taints & (1 << TAINT_CRAP))
- buf[l++] = 'C';
- if (mod->taints & (1 << TAINT_UNSIGNED_MODULE))
- buf[l++] = 'E';
- if (mod->taints & (1 << TAINT_LIVEPATCH))
- buf[l++] = 'K';
- /*
- * TAINT_FORCED_RMMOD: could be added.
- * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
- * apply to modules.
- */
return l;
}
@@ -1911,6 +1903,9 @@ static void frob_writable_data(const struct module_layout *layout,
/* livepatching wants to disable read-only so it can frob module. */
void module_disable_ro(const struct module *mod)
{
+ if (!rodata_enabled)
+ return;
+
frob_text(&mod->core_layout, set_memory_rw);
frob_rodata(&mod->core_layout, set_memory_rw);
frob_ro_after_init(&mod->core_layout, set_memory_rw);
@@ -1920,6 +1915,9 @@ void module_disable_ro(const struct module *mod)
void module_enable_ro(const struct module *mod, bool after_init)
{
+ if (!rodata_enabled)
+ return;
+
frob_text(&mod->core_layout, set_memory_ro);
frob_rodata(&mod->core_layout, set_memory_ro);
frob_text(&mod->init_layout, set_memory_ro);
@@ -1952,6 +1950,9 @@ void set_all_modules_text_rw(void)
{
struct module *mod;
+ if (!rodata_enabled)
+ return;
+
mutex_lock(&module_mutex);
list_for_each_entry_rcu(mod, &modules, list) {
if (mod->state == MODULE_STATE_UNFORMED)
@@ -1968,9 +1969,18 @@ void set_all_modules_text_ro(void)
{
struct module *mod;
+ if (!rodata_enabled)
+ return;
+
mutex_lock(&module_mutex);
list_for_each_entry_rcu(mod, &modules, list) {
- if (mod->state == MODULE_STATE_UNFORMED)
+ /*
+ * Ignore going modules since it's possible that ro
+ * protection has already been disabled, otherwise we'll
+ * run into protection faults at module deallocation.
+ */
+ if (mod->state == MODULE_STATE_UNFORMED ||
+ mod->state == MODULE_STATE_GOING)
continue;
frob_text(&mod->core_layout, set_memory_ro);
@@ -1981,10 +1991,12 @@ void set_all_modules_text_ro(void)
static void disable_ro_nx(const struct module_layout *layout)
{
- frob_text(layout, set_memory_rw);
- frob_rodata(layout, set_memory_rw);
+ if (rodata_enabled) {
+ frob_text(layout, set_memory_rw);
+ frob_rodata(layout, set_memory_rw);
+ frob_ro_after_init(layout, set_memory_rw);
+ }
frob_rodata(layout, set_memory_x);
- frob_ro_after_init(layout, set_memory_rw);
frob_ro_after_init(layout, set_memory_x);
frob_writable_data(layout, set_memory_x);
}
@@ -3709,6 +3721,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
sysfs_cleanup:
mod_sysfs_teardown(mod);
coming_cleanup:
+ mod->state = MODULE_STATE_GOING;
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_GOING, mod);
klp_module_going(mod);
@@ -4042,6 +4055,10 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
}
#endif /* CONFIG_KALLSYMS */
+/* Maximum number of characters written by module_flags() */
+#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
+
+/* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
static char *module_flags(struct module *mod, char *buf)
{
int bx = 0;
@@ -4086,7 +4103,7 @@ static void m_stop(struct seq_file *m, void *p)
static int m_show(struct seq_file *m, void *p)
{
struct module *mod = list_entry(p, struct module, list);
- char buf[8];
+ char buf[MODULE_FLAGS_BUF_SIZE];
/* We always ignore unformed modules. */
if (mod->state == MODULE_STATE_UNFORMED)
@@ -4257,7 +4274,7 @@ EXPORT_SYMBOL_GPL(__module_text_address);
void print_modules(void)
{
struct module *mod;
- char buf[8];
+ char buf[MODULE_FLAGS_BUF_SIZE];
printk(KERN_DEFAULT "Modules linked in:");
/* Most callers should already have preempt disabled, but make sure */
diff --git a/kernel/panic.c b/kernel/panic.c
index e6480e20379e..c51edaa04fce 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -298,30 +298,27 @@ void panic(const char *fmt, ...)
EXPORT_SYMBOL(panic);
-
-struct tnt {
- u8 bit;
- char true;
- char false;
-};
-
-static const struct tnt tnts[] = {
- { TAINT_PROPRIETARY_MODULE, 'P', 'G' },
- { TAINT_FORCED_MODULE, 'F', ' ' },
- { TAINT_CPU_OUT_OF_SPEC, 'S', ' ' },
- { TAINT_FORCED_RMMOD, 'R', ' ' },
- { TAINT_MACHINE_CHECK, 'M', ' ' },
- { TAINT_BAD_PAGE, 'B', ' ' },
- { TAINT_USER, 'U', ' ' },
- { TAINT_DIE, 'D', ' ' },
- { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
- { TAINT_WARN, 'W', ' ' },
- { TAINT_CRAP, 'C', ' ' },
- { TAINT_FIRMWARE_WORKAROUND, 'I', ' ' },
- { TAINT_OOT_MODULE, 'O', ' ' },
- { TAINT_UNSIGNED_MODULE, 'E', ' ' },
- { TAINT_SOFTLOCKUP, 'L', ' ' },
- { TAINT_LIVEPATCH, 'K', ' ' },
+/*
+ * TAINT_FORCED_RMMOD could be a per-module flag but the module
+ * is being removed anyway.
+ */
+const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
+ { 'P', 'G', true }, /* TAINT_PROPRIETARY_MODULE */
+ { 'F', ' ', true }, /* TAINT_FORCED_MODULE */
+ { 'S', ' ', false }, /* TAINT_CPU_OUT_OF_SPEC */
+ { 'R', ' ', false }, /* TAINT_FORCED_RMMOD */
+ { 'M', ' ', false }, /* TAINT_MACHINE_CHECK */
+ { 'B', ' ', false }, /* TAINT_BAD_PAGE */
+ { 'U', ' ', false }, /* TAINT_USER */
+ { 'D', ' ', false }, /* TAINT_DIE */
+ { 'A', ' ', false }, /* TAINT_OVERRIDDEN_ACPI_TABLE */
+ { 'W', ' ', false }, /* TAINT_WARN */
+ { 'C', ' ', true }, /* TAINT_CRAP */
+ { 'I', ' ', false }, /* TAINT_FIRMWARE_WORKAROUND */
+ { 'O', ' ', true }, /* TAINT_OOT_MODULE */
+ { 'E', ' ', true }, /* TAINT_UNSIGNED_MODULE */
+ { 'L', ' ', false }, /* TAINT_SOFTLOCKUP */
+ { 'K', ' ', true }, /* TAINT_LIVEPATCH */
};
/**
@@ -348,16 +345,16 @@ static const struct tnt tnts[] = {
*/
const char *print_tainted(void)
{
- static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ")];
+ static char buf[TAINT_FLAGS_COUNT + sizeof("Tainted: ")];
if (tainted_mask) {
char *s;
int i;
s = buf + sprintf(buf, "Tainted: ");
- for (i = 0; i < ARRAY_SIZE(tnts); i++) {
- const struct tnt *t = &tnts[i];
- *s++ = test_bit(t->bit, &tainted_mask) ?
+ for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
+ const struct taint_flag *t = &taint_flags[i];
+ *s++ = test_bit(i, &tainted_mask) ?
t->true : t->false;
}
*s = 0;
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index a3ce35e0fa1e..bc2e220ed2b0 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -356,7 +356,6 @@ DECLARE_WAIT_QUEUE_HEAD(log_wait);
/* the next printk record to read by syslog(READ) or /proc/kmsg */
static u64 syslog_seq;
static u32 syslog_idx;
-static enum log_flags syslog_prev;
static size_t syslog_partial;
/* index and sequence number of the first record stored in the buffer */
@@ -370,7 +369,6 @@ static u32 log_next_idx;
/* the next printk record to write to the console */
static u64 console_seq;
static u32 console_idx;
-static enum log_flags console_prev;
/* the next printk record to read after the last 'clear' command */
static u64 clear_seq;
@@ -639,27 +637,15 @@ static void append_char(char **pp, char *e, char c)
}
static ssize_t msg_print_ext_header(char *buf, size_t size,
- struct printk_log *msg, u64 seq,
- enum log_flags prev_flags)
+ struct printk_log *msg, u64 seq)
{
u64 ts_usec = msg->ts_nsec;
- char cont = '-';
do_div(ts_usec, 1000);
- /*
- * If we couldn't merge continuation line fragments during the print,
- * export the stored flags to allow an optional external merge of the
- * records. Merging the records isn't always neccessarily correct, like
- * when we hit a race during printing. In most cases though, it produces
- * better readable output. 'c' in the record flags mark the first
- * fragment of a line, '+' the following.
- */
- if (msg->flags & LOG_CONT)
- cont = (prev_flags & LOG_CONT) ? '+' : 'c';
-
return scnprintf(buf, size, "%u,%llu,%llu,%c;",
- (msg->facility << 3) | msg->level, seq, ts_usec, cont);
+ (msg->facility << 3) | msg->level, seq, ts_usec,
+ msg->flags & LOG_CONT ? 'c' : '-');
}
static ssize_t msg_print_ext_body(char *buf, size_t size,
@@ -714,7 +700,6 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
struct devkmsg_user {
u64 seq;
u32 idx;
- enum log_flags prev;
struct ratelimit_state rs;
struct mutex lock;
char buf[CONSOLE_EXT_LOG_MAX];
@@ -824,12 +809,11 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
msg = log_from_idx(user->idx);
len = msg_print_ext_header(user->buf, sizeof(user->buf),
- msg, user->seq, user->prev);
+ msg, user->seq);
len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
log_dict(msg), msg->dict_len,
log_text(msg), msg->text_len);
- user->prev = msg->flags;
user->idx = log_next(user->idx);
user->seq++;
raw_spin_unlock_irq(&logbuf_lock);
@@ -1210,26 +1194,12 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
return len;
}
-static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
- bool syslog, char *buf, size_t size)
+static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *buf, size_t size)
{
const char *text = log_text(msg);
size_t text_size = msg->text_len;
- bool prefix = true;
- bool newline = true;
size_t len = 0;
- if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
- prefix = false;
-
- if (msg->flags & LOG_CONT) {
- if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
- prefix = false;
-
- if (!(msg->flags & LOG_NEWLINE))
- newline = false;
- }
-
do {
const char *next = memchr(text, '\n', text_size);
size_t text_len;
@@ -1247,22 +1217,17 @@ static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
text_len + 1 >= size - len)
break;
- if (prefix)
- len += print_prefix(msg, syslog, buf + len);
+ len += print_prefix(msg, syslog, buf + len);
memcpy(buf + len, text, text_len);
len += text_len;
- if (next || newline)
- buf[len++] = '\n';
+ buf[len++] = '\n';
} else {
/* SYSLOG_ACTION_* buffer size only calculation */
- if (prefix)
- len += print_prefix(msg, syslog, NULL);
+ len += print_prefix(msg, syslog, NULL);
len += text_len;
- if (next || newline)
- len++;
+ len++;
}
- prefix = true;
text = next;
} while (text);
@@ -1288,7 +1253,6 @@ static int syslog_print(char __user *buf, int size)
/* messages are gone, move to first one */
syslog_seq = log_first_seq;
syslog_idx = log_first_idx;
- syslog_prev = 0;
syslog_partial = 0;
}
if (syslog_seq == log_next_seq) {
@@ -1298,13 +1262,11 @@ static int syslog_print(char __user *buf, int size)
skip = syslog_partial;
msg = log_from_idx(syslog_idx);
- n = msg_print_text(msg, syslog_prev, true, text,
- LOG_LINE_MAX + PREFIX_MAX);
+ n = msg_print_text(msg, true, text, LOG_LINE_MAX + PREFIX_MAX);
if (n - syslog_partial <= size) {
/* message fits into buffer, move forward */
syslog_idx = log_next(syslog_idx);
syslog_seq++;
- syslog_prev = msg->flags;
n -= syslog_partial;
syslog_partial = 0;
} else if (!len){
@@ -1347,7 +1309,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
u64 next_seq;
u64 seq;
u32 idx;
- enum log_flags prev;
/*
* Find first record that fits, including all following records,
@@ -1355,12 +1316,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
*/
seq = clear_seq;
idx = clear_idx;
- prev = 0;
while (seq < log_next_seq) {
struct printk_log *msg = log_from_idx(idx);
- len += msg_print_text(msg, prev, true, NULL, 0);
- prev = msg->flags;
+ len += msg_print_text(msg, true, NULL, 0);
idx = log_next(idx);
seq++;
}
@@ -1368,12 +1327,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
/* move first record forward until length fits into the buffer */
seq = clear_seq;
idx = clear_idx;
- prev = 0;
while (len > size && seq < log_next_seq) {
struct printk_log *msg = log_from_idx(idx);
- len -= msg_print_text(msg, prev, true, NULL, 0);
- prev = msg->flags;
+ len -= msg_print_text(msg, true, NULL, 0);
idx = log_next(idx);
seq++;
}
@@ -1386,7 +1343,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
struct printk_log *msg = log_from_idx(idx);
int textlen;
- textlen = msg_print_text(msg, prev, true, text,
+ textlen = msg_print_text(msg, true, text,
LOG_LINE_MAX + PREFIX_MAX);
if (textlen < 0) {
len = textlen;
@@ -1394,7 +1351,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
}
idx = log_next(idx);
seq++;
- prev = msg->flags;
raw_spin_unlock_irq(&logbuf_lock);
if (copy_to_user(buf + len, text, textlen))
@@ -1407,7 +1363,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
/* messages are gone, move to next one */
seq = log_first_seq;
idx = log_first_idx;
- prev = 0;
}
}
}
@@ -1508,7 +1463,6 @@ int do_syslog(int type, char __user *buf, int len, int source)
/* messages are gone, move to first one */
syslog_seq = log_first_seq;
syslog_idx = log_first_idx;
- syslog_prev = 0;
syslog_partial = 0;
}
if (source == SYSLOG_FROM_PROC) {
@@ -1521,16 +1475,14 @@ int do_syslog(int type, char __user *buf, int len, int source)
} else {
u64 seq = syslog_seq;
u32 idx = syslog_idx;
- enum log_flags prev = syslog_prev;
error = 0;
while (seq < log_next_seq) {
struct printk_log *msg = log_from_idx(idx);
- error += msg_print_text(msg, prev, true, NULL, 0);
+ error += msg_print_text(msg, true, NULL, 0);
idx = log_next(idx);
seq++;
- prev = msg->flags;
}
error -= syslog_partial;
}
@@ -1631,46 +1583,25 @@ static inline void printk_delay(void)
static struct cont {
char buf[LOG_LINE_MAX];
size_t len; /* length == 0 means unused buffer */
- size_t cons; /* bytes written to console */
struct task_struct *owner; /* task of first print*/
u64 ts_nsec; /* time of first print */
u8 level; /* log level of first message */
u8 facility; /* log facility of first message */
enum log_flags flags; /* prefix, newline flags */
- bool flushed:1; /* buffer sealed and committed */
} cont;
static void cont_flush(void)
{
- if (cont.flushed)
- return;
if (cont.len == 0)
return;
- if (cont.cons) {
- /*
- * If a fragment of this line was directly flushed to the
- * console; wait for the console to pick up the rest of the
- * line. LOG_NOCONS suppresses a duplicated output.
- */
- log_store(cont.facility, cont.level, cont.flags | LOG_NOCONS,
- cont.ts_nsec, NULL, 0, cont.buf, cont.len);
- cont.flushed = true;
- } else {
- /*
- * If no fragment of this line ever reached the console,
- * just submit it to the store and free the buffer.
- */
- log_store(cont.facility, cont.level, cont.flags, 0,
- NULL, 0, cont.buf, cont.len);
- cont.len = 0;
- }
+
+ log_store(cont.facility, cont.level, cont.flags, cont.ts_nsec,
+ NULL, 0, cont.buf, cont.len);
+ cont.len = 0;
}
static bool cont_add(int facility, int level, enum log_flags flags, const char *text, size_t len)
{
- if (cont.len && cont.flushed)
- return false;
-
/*
* If ext consoles are present, flush and skip in-kernel
* continuation. See nr_ext_console_drivers definition. Also, if
@@ -1687,8 +1618,6 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char *
cont.owner = current;
cont.ts_nsec = local_clock();
cont.flags = flags;
- cont.cons = 0;
- cont.flushed = false;
}
memcpy(cont.buf + cont.len, text, len);
@@ -1707,34 +1636,6 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char *
return true;
}
-static size_t cont_print_text(char *text, size_t size)
-{
- size_t textlen = 0;
- size_t len;
-
- if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) {
- textlen += print_time(cont.ts_nsec, text);
- size -= textlen;
- }
-
- len = cont.len - cont.cons;
- if (len > 0) {
- if (len+1 > size)
- len = size-1;
- memcpy(text + textlen, cont.buf + cont.cons, len);
- textlen += len;
- cont.cons = cont.len;
- }
-
- if (cont.flushed) {
- if (cont.flags & LOG_NEWLINE)
- text[textlen++] = '\n';
- /* got everything, release buffer */
- cont.len = 0;
- }
- return textlen;
-}
-
static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len)
{
/*
@@ -1981,33 +1882,24 @@ static u64 syslog_seq;
static u32 syslog_idx;
static u64 console_seq;
static u32 console_idx;
-static enum log_flags syslog_prev;
static u64 log_first_seq;
static u32 log_first_idx;
static u64 log_next_seq;
-static enum log_flags console_prev;
-static struct cont {
- size_t len;
- size_t cons;
- u8 level;
- bool flushed:1;
-} cont;
static char *log_text(const struct printk_log *msg) { return NULL; }
static char *log_dict(const struct printk_log *msg) { return NULL; }
static struct printk_log *log_from_idx(u32 idx) { return NULL; }
static u32 log_next(u32 idx) { return 0; }
static ssize_t msg_print_ext_header(char *buf, size_t size,
- struct printk_log *msg, u64 seq,
- enum log_flags prev_flags) { return 0; }
+ struct printk_log *msg,
+ u64 seq) { return 0; }
static ssize_t msg_print_ext_body(char *buf, size_t size,
char *dict, size_t dict_len,
char *text, size_t text_len) { return 0; }
static void call_console_drivers(int level,
const char *ext_text, size_t ext_len,
const char *text, size_t len) {}
-static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
+static size_t msg_print_text(const struct printk_log *msg,
bool syslog, char *buf, size_t size) { return 0; }
-static size_t cont_print_text(char *text, size_t size) { return 0; }
static bool suppress_message_printing(int level) { return false; }
/* Still needs to be defined for users */
@@ -2271,42 +2163,6 @@ static inline int can_use_console(void)
return cpu_online(raw_smp_processor_id()) || have_callable_console();
}
-static void console_cont_flush(char *text, size_t size)
-{
- unsigned long flags;
- size_t len;
-
- raw_spin_lock_irqsave(&logbuf_lock, flags);
-
- if (!cont.len)
- goto out;
-
- if (suppress_message_printing(cont.level)) {
- cont.cons = cont.len;
- if (cont.flushed)
- cont.len = 0;
- goto out;
- }
-
- /*
- * We still queue earlier records, likely because the console was
- * busy. The earlier ones need to be printed before this one, we
- * did not flush any fragment so far, so just let it queue up.
- */
- if (console_seq < log_next_seq && !cont.cons)
- goto out;
-
- len = cont_print_text(text, size);
- raw_spin_unlock(&logbuf_lock);
- stop_critical_timings();
- call_console_drivers(cont.level, NULL, 0, text, len);
- start_critical_timings();
- local_irq_restore(flags);
- return;
-out:
- raw_spin_unlock_irqrestore(&logbuf_lock, flags);
-}
-
/**
* console_unlock - unlock the console system
*
@@ -2360,9 +2216,6 @@ again:
return;
}
- /* flush buffered message fragment immediately to console */
- console_cont_flush(text, sizeof(text));
-
for (;;) {
struct printk_log *msg;
size_t ext_len = 0;
@@ -2382,7 +2235,6 @@ again:
/* messages are gone, move to first one */
console_seq = log_first_seq;
console_idx = log_first_idx;
- console_prev = 0;
} else {
len = 0;
}
@@ -2392,8 +2244,7 @@ skip:
msg = log_from_idx(console_idx);
level = msg->level;
- if ((msg->flags & LOG_NOCONS) ||
- suppress_message_printing(level)) {
+ if (suppress_message_printing(level)) {
/*
* Skip record we have buffered and already printed
* directly to the console when we received it, and
@@ -2401,22 +2252,14 @@ skip:
*/
console_idx = log_next(console_idx);
console_seq++;
- /*
- * We will get here again when we register a new
- * CON_PRINTBUFFER console. Clear the flag so we
- * will properly dump everything later.
- */
- msg->flags &= ~LOG_NOCONS;
- console_prev = msg->flags;
goto skip;
}
- len += msg_print_text(msg, console_prev, false,
- text + len, sizeof(text) - len);
+ len += msg_print_text(msg, false, text + len, sizeof(text) - len);
if (nr_ext_console_drivers) {
ext_len = msg_print_ext_header(ext_text,
sizeof(ext_text),
- msg, console_seq, console_prev);
+ msg, console_seq);
ext_len += msg_print_ext_body(ext_text + ext_len,
sizeof(ext_text) - ext_len,
log_dict(msg), msg->dict_len,
@@ -2424,7 +2267,6 @@ skip:
}
console_idx = log_next(console_idx);
console_seq++;
- console_prev = msg->flags;
raw_spin_unlock(&logbuf_lock);
stop_critical_timings(); /* don't trace print latency */
@@ -2719,7 +2561,6 @@ void register_console(struct console *newcon)
raw_spin_lock_irqsave(&logbuf_lock, flags);
console_seq = syslog_seq;
console_idx = syslog_idx;
- console_prev = syslog_prev;
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
/*
* We're about to replay the log buffer. Only do this to the
@@ -3075,7 +2916,7 @@ bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
goto out;
msg = log_from_idx(dumper->cur_idx);
- l = msg_print_text(msg, 0, syslog, line, size);
+ l = msg_print_text(msg, syslog, line, size);
dumper->cur_idx = log_next(dumper->cur_idx);
dumper->cur_seq++;
@@ -3144,7 +2985,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
u32 idx;
u64 next_seq;
u32 next_idx;
- enum log_flags prev;
size_t l = 0;
bool ret = false;
@@ -3167,27 +3007,23 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
/* calculate length of entire buffer */
seq = dumper->cur_seq;
idx = dumper->cur_idx;
- prev = 0;
while (seq < dumper->next_seq) {
struct printk_log *msg = log_from_idx(idx);
- l += msg_print_text(msg, prev, true, NULL, 0);
+ l += msg_print_text(msg, true, NULL, 0);
idx = log_next(idx);
seq++;
- prev = msg->flags;
}
/* move first record forward until length fits into the buffer */
seq = dumper->cur_seq;
idx = dumper->cur_idx;
- prev = 0;
while (l > size && seq < dumper->next_seq) {
struct printk_log *msg = log_from_idx(idx);
- l -= msg_print_text(msg, prev, true, NULL, 0);
+ l -= msg_print_text(msg, true, NULL, 0);
idx = log_next(idx);
seq++;
- prev = msg->flags;
}
/* last message in next interation */
@@ -3198,10 +3034,9 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
while (seq < dumper->next_seq) {
struct printk_log *msg = log_from_idx(idx);
- l += msg_print_text(msg, prev, syslog, buf + l, size - l);
+ l += msg_print_text(msg, syslog, buf + l, size - l);
idx = log_next(idx);
seq++;
- prev = msg->flags;
}
dumper->next_seq = next_seq;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 1475d2545b7e..1a292ebcbbb6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -627,7 +627,7 @@ static struct ctl_table kern_table[] = {
.data = &tracepoint_printk,
.maxlen = sizeof(tracepoint_printk),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = tracepoint_printk_sysctl,
},
#endif
#ifdef CONFIG_KEXEC_CORE
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 2a96b063d659..d5038005eb5d 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -70,6 +70,7 @@ config FTRACE_NMI_ENTER
config EVENT_TRACING
select CONTEXT_SWITCH_TRACER
+ select GLOB
bool
config CONTEXT_SWITCH_TRACER
@@ -133,6 +134,7 @@ config FUNCTION_TRACER
select KALLSYMS
select GENERIC_TRACER
select CONTEXT_SWITCH_TRACER
+ select GLOB
help
Enable the kernel to trace every kernel function. This is done
by using a compiler feature to insert a small, 5-byte No-Operation
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 33dd57f53f88..1f0f547c54da 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3511,6 +3511,10 @@ static int ftrace_match(char *str, struct ftrace_glob *g)
memcmp(str + slen - g->len, g->search, g->len) == 0)
matched = 1;
break;
+ case MATCH_GLOB:
+ if (glob_match(g->search, str))
+ matched = 1;
+ break;
}
return matched;
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 89a2611a1635..a85739efcc30 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -245,7 +245,7 @@ unsigned ring_buffer_event_length(struct ring_buffer_event *event)
EXPORT_SYMBOL_GPL(ring_buffer_event_length);
/* inline for ring buffer fast paths */
-static void *
+static __always_inline void *
rb_event_data(struct ring_buffer_event *event)
{
if (event->type_len == RINGBUF_TYPE_TIME_EXTEND)
@@ -1798,48 +1798,48 @@ void ring_buffer_change_overwrite(struct ring_buffer *buffer, int val)
}
EXPORT_SYMBOL_GPL(ring_buffer_change_overwrite);
-static inline void *
+static __always_inline void *
__rb_data_page_index(struct buffer_data_page *bpage, unsigned index)
{
return bpage->data + index;
}
-static inline void *__rb_page_index(struct buffer_page *bpage, unsigned index)
+static __always_inline void *__rb_page_index(struct buffer_page *bpage, unsigned index)
{
return bpage->page->data + index;
}
-static inline struct ring_buffer_event *
+static __always_inline struct ring_buffer_event *
rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer)
{
return __rb_page_index(cpu_buffer->reader_page,
cpu_buffer->reader_page->read);
}
-static inline struct ring_buffer_event *
+static __always_inline struct ring_buffer_event *
rb_iter_head_event(struct ring_buffer_iter *iter)
{
return __rb_page_index(iter->head_page, iter->head);
}
-static inline unsigned rb_page_commit(struct buffer_page *bpage)
+static __always_inline unsigned rb_page_commit(struct buffer_page *bpage)
{
return local_read(&bpage->page->commit);
}
/* Size is determined by what has been committed */
-static inline unsigned rb_page_size(struct buffer_page *bpage)
+static __always_inline unsigned rb_page_size(struct buffer_page *bpage)
{
return rb_page_commit(bpage);
}
-static inline unsigned
+static __always_inline unsigned
rb_commit_index(struct ring_buffer_per_cpu *cpu_buffer)
{
return rb_page_commit(cpu_buffer->commit_page);
}
-static inline unsigned
+static __always_inline unsigned
rb_event_index(struct ring_buffer_event *event)
{
unsigned long addr = (unsigned long)event;
@@ -2355,7 +2355,7 @@ static void rb_start_commit(struct ring_buffer_per_cpu *cpu_buffer)
local_inc(&cpu_buffer->commits);
}
-static void
+static __always_inline void
rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
{
unsigned long max_count;
@@ -2410,7 +2410,7 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
goto again;
}
-static inline void rb_end_commit(struct ring_buffer_per_cpu *cpu_buffer)
+static __always_inline void rb_end_commit(struct ring_buffer_per_cpu *cpu_buffer)
{
unsigned long commits;
@@ -2455,7 +2455,7 @@ static inline void rb_event_discard(struct ring_buffer_event *event)
event->time_delta = 1;
}
-static inline bool
+static __always_inline bool
rb_event_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer_event *event)
{
@@ -2469,7 +2469,7 @@ rb_event_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
rb_commit_index(cpu_buffer) == index;
}
-static void
+static __always_inline void
rb_update_write_stamp(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer_event *event)
{
@@ -2702,7 +2702,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
return event;
}
-static struct ring_buffer_event *
+static __always_inline struct ring_buffer_event *
rb_reserve_next_event(struct ring_buffer *buffer,
struct ring_buffer_per_cpu *cpu_buffer,
unsigned long length)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 54d5270a5042..66f829c47bec 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -40,6 +40,7 @@
#include <linux/poll.h>
#include <linux/nmi.h>
#include <linux/fs.h>
+#include <linux/trace.h>
#include <linux/sched/rt.h>
#include "trace.h"
@@ -68,6 +69,7 @@ bool __read_mostly tracing_selftest_disabled;
/* Pipe tracepoints to printk */
struct trace_iterator *tracepoint_print_iter;
int tracepoint_printk;
+static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);
/* For tracers that don't implement custom flags */
static struct tracer_opt dummy_tracer_opt[] = {
@@ -738,6 +740,31 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
#endif
+static __always_inline void
+trace_event_setup(struct ring_buffer_event *event,
+ int type, unsigned long flags, int pc)
+{
+ struct trace_entry *ent = ring_buffer_event_data(event);
+
+ tracing_generic_entry_update(ent, flags, pc);
+ ent->type = type;
+}
+
+static __always_inline struct ring_buffer_event *
+__trace_buffer_lock_reserve(struct ring_buffer *buffer,
+ int type,
+ unsigned long len,
+ unsigned long flags, int pc)
+{
+ struct ring_buffer_event *event;
+
+ event = ring_buffer_lock_reserve(buffer, len);
+ if (event != NULL)
+ trace_event_setup(event, type, flags, pc);
+
+ return event;
+}
+
static void tracer_tracing_on(struct trace_array *tr)
{
if (tr->trace_buffer.buffer)
@@ -767,6 +794,22 @@ void tracing_on(void)
}
EXPORT_SYMBOL_GPL(tracing_on);
+
+static __always_inline void
+__buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event)
+{
+ __this_cpu_write(trace_cmdline_save, true);
+
+ /* If this is the temp buffer, we need to commit fully */
+ if (this_cpu_read(trace_buffered_event) == event) {
+ /* Length is in event->array[0] */
+ ring_buffer_write(buffer, event->array[0], &event->array[1]);
+ /* Release the temp buffer */
+ this_cpu_dec(trace_buffered_event_cnt);
+ } else
+ ring_buffer_unlock_commit(buffer, event);
+}
+
/**
* __trace_puts - write a constant string into the trace buffer.
* @ip: The address of the caller
@@ -794,8 +837,8 @@ int __trace_puts(unsigned long ip, const char *str, int size)
local_save_flags(irq_flags);
buffer = global_trace.trace_buffer.buffer;
- event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc,
- irq_flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc,
+ irq_flags, pc);
if (!event)
return 0;
@@ -842,8 +885,8 @@ int __trace_bputs(unsigned long ip, const char *str)
local_save_flags(irq_flags);
buffer = global_trace.trace_buffer.buffer;
- event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size,
- irq_flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size,
+ irq_flags, pc);
if (!event)
return 0;
@@ -1907,35 +1950,19 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
#endif
((pc & NMI_MASK ) ? TRACE_FLAG_NMI : 0) |
((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
- ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
+ ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) |
(tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) |
(test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0);
}
EXPORT_SYMBOL_GPL(tracing_generic_entry_update);
-static __always_inline void
-trace_event_setup(struct ring_buffer_event *event,
- int type, unsigned long flags, int pc)
-{
- struct trace_entry *ent = ring_buffer_event_data(event);
-
- tracing_generic_entry_update(ent, flags, pc);
- ent->type = type;
-}
-
struct ring_buffer_event *
trace_buffer_lock_reserve(struct ring_buffer *buffer,
int type,
unsigned long len,
unsigned long flags, int pc)
{
- struct ring_buffer_event *event;
-
- event = ring_buffer_lock_reserve(buffer, len);
- if (event != NULL)
- trace_event_setup(event, type, flags, pc);
-
- return event;
+ return __trace_buffer_lock_reserve(buffer, type, len, flags, pc);
}
DEFINE_PER_CPU(struct ring_buffer_event *, trace_buffered_event);
@@ -2049,21 +2076,6 @@ void trace_buffered_event_disable(void)
preempt_enable();
}
-void
-__buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event)
-{
- __this_cpu_write(trace_cmdline_save, true);
-
- /* If this is the temp buffer, we need to commit fully */
- if (this_cpu_read(trace_buffered_event) == event) {
- /* Length is in event->array[0] */
- ring_buffer_write(buffer, event->array[0], &event->array[1]);
- /* Release the temp buffer */
- this_cpu_dec(trace_buffered_event_cnt);
- } else
- ring_buffer_unlock_commit(buffer, event);
-}
-
static struct ring_buffer *temp_buffer;
struct ring_buffer_event *
@@ -2090,8 +2102,8 @@ trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
this_cpu_dec(trace_buffered_event_cnt);
}
- entry = trace_buffer_lock_reserve(*current_rb,
- type, len, flags, pc);
+ entry = __trace_buffer_lock_reserve(*current_rb,
+ type, len, flags, pc);
/*
* If tracing is off, but we have triggers enabled
* we still need to look at the event data. Use the temp_buffer
@@ -2100,13 +2112,88 @@ trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
*/
if (!entry && trace_file->flags & EVENT_FILE_FL_TRIGGER_COND) {
*current_rb = temp_buffer;
- entry = trace_buffer_lock_reserve(*current_rb,
- type, len, flags, pc);
+ entry = __trace_buffer_lock_reserve(*current_rb,
+ type, len, flags, pc);
}
return entry;
}
EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve);
+static DEFINE_SPINLOCK(tracepoint_iter_lock);
+static DEFINE_MUTEX(tracepoint_printk_mutex);
+
+static void output_printk(struct trace_event_buffer *fbuffer)
+{
+ struct trace_event_call *event_call;
+ struct trace_event *event;
+ unsigned long flags;
+ struct trace_iterator *iter = tracepoint_print_iter;
+
+ /* We should never get here if iter is NULL */
+ if (WARN_ON_ONCE(!iter))
+ return;
+
+ event_call = fbuffer->trace_file->event_call;
+ if (!event_call || !event_call->event.funcs ||
+ !event_call->event.funcs->trace)
+ return;
+
+ event = &fbuffer->trace_file->event_call->event;
+
+ spin_lock_irqsave(&tracepoint_iter_lock, flags);
+ trace_seq_init(&iter->seq);
+ iter->ent = fbuffer->entry;
+ event_call->event.funcs->trace(iter, 0, event);
+ trace_seq_putc(&iter->seq, 0);
+ printk("%s", iter->seq.buffer);
+
+ spin_unlock_irqrestore(&tracepoint_iter_lock, flags);
+}
+
+int tracepoint_printk_sysctl(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ int save_tracepoint_printk;
+ int ret;
+
+ mutex_lock(&tracepoint_printk_mutex);
+ save_tracepoint_printk = tracepoint_printk;
+
+ ret = proc_dointvec(table, write, buffer, lenp, ppos);
+
+ /*
+ * This will force exiting early, as tracepoint_printk
+ * is always zero when tracepoint_printk_iter is not allocated
+ */
+ if (!tracepoint_print_iter)
+ tracepoint_printk = 0;
+
+ if (save_tracepoint_printk == tracepoint_printk)
+ goto out;
+
+ if (tracepoint_printk)
+ static_key_enable(&tracepoint_printk_key.key);
+ else
+ static_key_disable(&tracepoint_printk_key.key);
+
+ out:
+ mutex_unlock(&tracepoint_printk_mutex);
+
+ return ret;
+}
+
+void trace_event_buffer_commit(struct trace_event_buffer *fbuffer)
+{
+ if (static_key_false(&tracepoint_printk_key.key))
+ output_printk(fbuffer);
+
+ event_trigger_unlock_commit(fbuffer->trace_file, fbuffer->buffer,
+ fbuffer->event, fbuffer->entry,
+ fbuffer->flags, fbuffer->pc);
+}
+EXPORT_SYMBOL_GPL(trace_event_buffer_commit);
+
void trace_buffer_unlock_commit_regs(struct trace_array *tr,
struct ring_buffer *buffer,
struct ring_buffer_event *event,
@@ -2129,6 +2216,139 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
ftrace_trace_userstack(buffer, flags, pc);
}
+/*
+ * Similar to trace_buffer_unlock_commit_regs() but do not dump stack.
+ */
+void
+trace_buffer_unlock_commit_nostack(struct ring_buffer *buffer,
+ struct ring_buffer_event *event)
+{
+ __buffer_unlock_commit(buffer, event);
+}
+
+static void
+trace_process_export(struct trace_export *export,
+ struct ring_buffer_event *event)
+{
+ struct trace_entry *entry;
+ unsigned int size = 0;
+
+ entry = ring_buffer_event_data(event);
+ size = ring_buffer_event_length(event);
+ export->write(entry, size);
+}
+
+static DEFINE_MUTEX(ftrace_export_lock);
+
+static struct trace_export __rcu *ftrace_exports_list __read_mostly;
+
+static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
+
+static inline void ftrace_exports_enable(void)
+{
+ static_branch_enable(&ftrace_exports_enabled);
+}
+
+static inline void ftrace_exports_disable(void)
+{
+ static_branch_disable(&ftrace_exports_enabled);
+}
+
+void ftrace_exports(struct ring_buffer_event *event)
+{
+ struct trace_export *export;
+
+ preempt_disable_notrace();
+
+ export = rcu_dereference_raw_notrace(ftrace_exports_list);
+ while (export) {
+ trace_process_export(export, event);
+ export = rcu_dereference_raw_notrace(export->next);
+ }
+
+ preempt_enable_notrace();
+}
+
+static inline void
+add_trace_export(struct trace_export **list, struct trace_export *export)
+{
+ rcu_assign_pointer(export->next, *list);
+ /*
+ * We are entering export into the list but another
+ * CPU might be walking that list. We need to make sure
+ * the export->next pointer is valid before another CPU sees
+ * the export pointer included into the list.
+ */
+ rcu_assign_pointer(*list, export);
+}
+
+static inline int
+rm_trace_export(struct trace_export **list, struct trace_export *export)
+{
+ struct trace_export **p;
+
+ for (p = list; *p != NULL; p = &(*p)->next)
+ if (*p == export)
+ break;
+
+ if (*p != export)
+ return -1;
+
+ rcu_assign_pointer(*p, (*p)->next);
+
+ return 0;
+}
+
+static inline void
+add_ftrace_export(struct trace_export **list, struct trace_export *export)
+{
+ if (*list == NULL)
+ ftrace_exports_enable();
+
+ add_trace_export(list, export);
+}
+
+static inline int
+rm_ftrace_export(struct trace_export **list, struct trace_export *export)
+{
+ int ret;
+
+ ret = rm_trace_export(list, export);
+ if (*list == NULL)
+ ftrace_exports_disable();
+
+ return ret;
+}
+
+int register_ftrace_export(struct trace_export *export)
+{
+ if (WARN_ON_ONCE(!export->write))
+ return -1;
+
+ mutex_lock(&ftrace_export_lock);
+
+ add_ftrace_export(&ftrace_exports_list, export);
+
+ mutex_unlock(&ftrace_export_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(register_ftrace_export);
+
+int unregister_ftrace_export(struct trace_export *export)
+{
+ int ret;
+
+ mutex_lock(&ftrace_export_lock);
+
+ ret = rm_ftrace_export(&ftrace_exports_list, export);
+
+ mutex_unlock(&ftrace_export_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(unregister_ftrace_export);
+
void
trace_function(struct trace_array *tr,
unsigned long ip, unsigned long parent_ip, unsigned long flags,
@@ -2139,16 +2359,19 @@ trace_function(struct trace_array *tr,
struct ring_buffer_event *event;
struct ftrace_entry *entry;
- event = trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry),
- flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry),
+ flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
entry->ip = ip;
entry->parent_ip = parent_ip;
- if (!call_filter_check_discard(call, entry, buffer, event))
+ if (!call_filter_check_discard(call, entry, buffer, event)) {
+ if (static_branch_unlikely(&ftrace_exports_enabled))
+ ftrace_exports(event);
__buffer_unlock_commit(buffer, event);
+ }
}
#ifdef CONFIG_STACKTRACE
@@ -2216,8 +2439,8 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,
size *= sizeof(unsigned long);
- event = trace_buffer_lock_reserve(buffer, TRACE_STACK,
- sizeof(*entry) + size, flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_STACK,
+ sizeof(*entry) + size, flags, pc);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
@@ -2318,8 +2541,8 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
__this_cpu_inc(user_stack_count);
- event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK,
- sizeof(*entry), flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_USER_STACK,
+ sizeof(*entry), flags, pc);
if (!event)
goto out_drop_count;
entry = ring_buffer_event_data(event);
@@ -2489,8 +2712,8 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
local_save_flags(flags);
size = sizeof(*entry) + sizeof(u32) * len;
buffer = tr->trace_buffer.buffer;
- event = trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size,
- flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size,
+ flags, pc);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
@@ -2545,8 +2768,8 @@ __trace_array_vprintk(struct ring_buffer *buffer,
local_save_flags(flags);
size = sizeof(*entry) + len + 1;
- event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
- flags, pc);
+ event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
+ flags, pc);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
@@ -4055,6 +4278,7 @@ static const char readme_msg[] =
" x86-tsc: TSC cycle counter\n"
#endif
"\n trace_marker\t\t- Writes into this file writes into the kernel buffer\n"
+ "\n trace_marker_raw\t\t- Writes into this file writes binary data into the kernel buffer\n"
" tracing_cpumask\t- Limit which CPUs to trace\n"
" instances\t\t- Make sub-buffers with: mkdir instances/foo\n"
"\t\t\t Remove sub-buffer with rmdir\n"
@@ -4066,7 +4290,7 @@ static const char readme_msg[] =
"\n available_filter_functions - list of functions that can be filtered on\n"
" set_ftrace_filter\t- echo function name in here to only trace these\n"
"\t\t\t functions\n"
- "\t accepts: func_full_name, *func_end, func_begin*, *func_middle*\n"
+ "\t accepts: func_full_name or glob-matching-pattern\n"
"\t modules: Can select a group via module\n"
"\t Format: :mod:<module-name>\n"
"\t example: echo :mod:ext3 > set_ftrace_filter\n"
@@ -5519,21 +5743,18 @@ static ssize_t
tracing_mark_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *fpos)
{
- unsigned long addr = (unsigned long)ubuf;
struct trace_array *tr = filp->private_data;
struct ring_buffer_event *event;
struct ring_buffer *buffer;
struct print_entry *entry;
unsigned long irq_flags;
- struct page *pages[2];
- void *map_page[2];
- int nr_pages = 1;
+ const char faulted[] = "<faulted>";
ssize_t written;
- int offset;
int size;
int len;
- int ret;
- int i;
+
+/* Used in tracing_mark_raw_write() as well */
+#define FAULTED_SIZE (sizeof(faulted) - 1) /* '\0' is already accounted for */
if (tracing_disabled)
return -EINVAL;
@@ -5544,60 +5765,33 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
if (cnt > TRACE_BUF_SIZE)
cnt = TRACE_BUF_SIZE;
- /*
- * Userspace is injecting traces into the kernel trace buffer.
- * We want to be as non intrusive as possible.
- * To do so, we do not want to allocate any special buffers
- * or take any locks, but instead write the userspace data
- * straight into the ring buffer.
- *
- * First we need to pin the userspace buffer into memory,
- * which, most likely it is, because it just referenced it.
- * But there's no guarantee that it is. By using get_user_pages_fast()
- * and kmap_atomic/kunmap_atomic() we can get access to the
- * pages directly. We then write the data directly into the
- * ring buffer.
- */
BUILD_BUG_ON(TRACE_BUF_SIZE >= PAGE_SIZE);
- /* check if we cross pages */
- if ((addr & PAGE_MASK) != ((addr + cnt) & PAGE_MASK))
- nr_pages = 2;
-
- offset = addr & (PAGE_SIZE - 1);
- addr &= PAGE_MASK;
-
- ret = get_user_pages_fast(addr, nr_pages, 0, pages);
- if (ret < nr_pages) {
- while (--ret >= 0)
- put_page(pages[ret]);
- written = -EFAULT;
- goto out;
- }
+ local_save_flags(irq_flags);
+ size = sizeof(*entry) + cnt + 2; /* add '\0' and possible '\n' */
- for (i = 0; i < nr_pages; i++)
- map_page[i] = kmap_atomic(pages[i]);
+ /* If less than "<faulted>", then make sure we can still add that */
+ if (cnt < FAULTED_SIZE)
+ size += FAULTED_SIZE - cnt;
- local_save_flags(irq_flags);
- size = sizeof(*entry) + cnt + 2; /* possible \n added */
buffer = tr->trace_buffer.buffer;
- event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
- irq_flags, preempt_count());
- if (!event) {
+ event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
+ irq_flags, preempt_count());
+ if (unlikely(!event))
/* Ring buffer disabled, return as if not open for write */
- written = -EBADF;
- goto out_unlock;
- }
+ return -EBADF;
entry = ring_buffer_event_data(event);
entry->ip = _THIS_IP_;
- if (nr_pages == 2) {
- len = PAGE_SIZE - offset;
- memcpy(&entry->buf, map_page[0] + offset, len);
- memcpy(&entry->buf[len], map_page[1], cnt - len);
+ len = __copy_from_user_inatomic(&entry->buf, ubuf, cnt);
+ if (len) {
+ memcpy(&entry->buf, faulted, FAULTED_SIZE);
+ cnt = FAULTED_SIZE;
+ written = -EFAULT;
} else
- memcpy(&entry->buf, map_page[0] + offset, cnt);
+ written = cnt;
+ len = cnt;
if (entry->buf[cnt - 1] != '\n') {
entry->buf[cnt] = '\n';
@@ -5607,16 +5801,73 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
__buffer_unlock_commit(buffer, event);
- written = cnt;
+ if (written > 0)
+ *fpos += written;
- *fpos += written;
+ return written;
+}
+
+/* Limit it for now to 3K (including tag) */
+#define RAW_DATA_MAX_SIZE (1024*3)
+
+static ssize_t
+tracing_mark_raw_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *fpos)
+{
+ struct trace_array *tr = filp->private_data;
+ struct ring_buffer_event *event;
+ struct ring_buffer *buffer;
+ struct raw_data_entry *entry;
+ const char faulted[] = "<faulted>";
+ unsigned long irq_flags;
+ ssize_t written;
+ int size;
+ int len;
+
+#define FAULT_SIZE_ID (FAULTED_SIZE + sizeof(int))
+
+ if (tracing_disabled)
+ return -EINVAL;
+
+ if (!(tr->trace_flags & TRACE_ITER_MARKERS))
+ return -EINVAL;
+
+ /* The marker must at least have a tag id */
+ if (cnt < sizeof(unsigned int) || cnt > RAW_DATA_MAX_SIZE)
+ return -EINVAL;
+
+ if (cnt > TRACE_BUF_SIZE)
+ cnt = TRACE_BUF_SIZE;
+
+ BUILD_BUG_ON(TRACE_BUF_SIZE >= PAGE_SIZE);
+
+ local_save_flags(irq_flags);
+ size = sizeof(*entry) + cnt;
+ if (cnt < FAULT_SIZE_ID)
+ size += FAULT_SIZE_ID - cnt;
+
+ buffer = tr->trace_buffer.buffer;
+ event = __trace_buffer_lock_reserve(buffer, TRACE_RAW_DATA, size,
+ irq_flags, preempt_count());
+ if (!event)
+ /* Ring buffer disabled, return as if not open for write */
+ return -EBADF;
+
+ entry = ring_buffer_event_data(event);
+
+ len = __copy_from_user_inatomic(&entry->id, ubuf, cnt);
+ if (len) {
+ entry->id = -1;
+ memcpy(&entry->buf, faulted, FAULTED_SIZE);
+ written = -EFAULT;
+ } else
+ written = cnt;
+
+ __buffer_unlock_commit(buffer, event);
+
+ if (written > 0)
+ *fpos += written;
- out_unlock:
- for (i = nr_pages - 1; i >= 0; i--) {
- kunmap_atomic(map_page[i]);
- put_page(pages[i]);
- }
- out:
return written;
}
@@ -5946,6 +6197,13 @@ static const struct file_operations tracing_mark_fops = {
.release = tracing_release_generic_tr,
};
+static const struct file_operations tracing_mark_raw_fops = {
+ .open = tracing_open_generic_tr,
+ .write = tracing_mark_raw_write,
+ .llseek = generic_file_llseek,
+ .release = tracing_release_generic_tr,
+};
+
static const struct file_operations trace_clock_fops = {
.open = tracing_clock_open,
.read = seq_read,
@@ -7215,6 +7473,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
trace_create_file("trace_marker", 0220, d_tracer,
tr, &tracing_mark_fops);
+ trace_create_file("trace_marker_raw", 0220, d_tracer,
+ tr, &tracing_mark_raw_fops);
+
trace_create_file("trace_clock", 0644, d_tracer, tr,
&trace_clock_fops);
@@ -7752,6 +8013,8 @@ void __init trace_init(void)
kmalloc(sizeof(*tracepoint_print_iter), GFP_KERNEL);
if (WARN_ON(!tracepoint_print_iter))
tracepoint_printk = 0;
+ else
+ static_key_enable(&tracepoint_printk_key.key);
}
tracer_alloc_buffers();
trace_event_init();
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index fd24b1f9ac43..c2234494f40c 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -15,6 +15,7 @@
#include <linux/trace_events.h>
#include <linux/compiler.h>
#include <linux/trace_seq.h>
+#include <linux/glob.h>
#ifdef CONFIG_FTRACE_SYSCALLS
#include <asm/unistd.h> /* For NR_SYSCALLS */
@@ -39,6 +40,7 @@ enum trace_type {
TRACE_BLK,
TRACE_BPUTS,
TRACE_HWLAT,
+ TRACE_RAW_DATA,
__TRACE_LAST_TYPE,
};
@@ -330,6 +332,7 @@ extern void __ftrace_bad_type(void);
IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \
IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS); \
IF_ASSIGN(var, ent, struct hwlat_entry, TRACE_HWLAT); \
+ IF_ASSIGN(var, ent, struct raw_data_entry, TRACE_RAW_DATA);\
IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \
TRACE_MMIO_RW); \
IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \
@@ -599,8 +602,8 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
int *ent_cpu, u64 *ent_ts);
-void __buffer_unlock_commit(struct ring_buffer *buffer,
- struct ring_buffer_event *event);
+void trace_buffer_unlock_commit_nostack(struct ring_buffer *buffer,
+ struct ring_buffer_event *event);
int trace_empty(struct trace_iterator *iter);
@@ -843,6 +846,17 @@ static inline int ftrace_graph_notrace_addr(unsigned long addr)
return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
+
+extern unsigned int fgraph_max_depth;
+
+static inline bool ftrace_graph_ignore_func(struct ftrace_graph_ent *trace)
+{
+ /* trace it when it is-nested-in or is a function enabled. */
+ return !(trace->depth || ftrace_graph_addr(trace->func)) ||
+ (trace->depth < 0) ||
+ (fgraph_max_depth && trace->depth >= fgraph_max_depth);
+}
+
#else /* CONFIG_FUNCTION_GRAPH_TRACER */
static inline enum print_line_t
print_graph_function_flags(struct trace_iterator *iter, u32 flags)
@@ -1257,6 +1271,7 @@ enum regex_type {
MATCH_FRONT_ONLY,
MATCH_MIDDLE_ONLY,
MATCH_END_ONLY,
+ MATCH_GLOB,
};
struct regex {
diff --git a/kernel/trace/trace_benchmark.c b/kernel/trace/trace_benchmark.c
index 0f109c4130d3..e3b488825ae3 100644
--- a/kernel/trace/trace_benchmark.c
+++ b/kernel/trace/trace_benchmark.c
@@ -21,6 +21,8 @@ static u64 bm_stddev;
static unsigned int bm_avg;
static unsigned int bm_std;
+static bool ok_to_run;
+
/*
* This gets called in a loop recording the time it took to write
* the tracepoint. What it writes is the time statistics of the last
@@ -164,11 +166,21 @@ static int benchmark_event_kthread(void *arg)
* When the benchmark tracepoint is enabled, it calls this
* function and the thread that calls the tracepoint is created.
*/
-void trace_benchmark_reg(void)
+int trace_benchmark_reg(void)
{
+ if (!ok_to_run) {
+ pr_warning("trace benchmark cannot be started via kernel command line\n");
+ return -EBUSY;
+ }
+
bm_event_thread = kthread_run(benchmark_event_kthread,
NULL, "event_benchmark");
- WARN_ON(!bm_event_thread);
+ if (!bm_event_thread) {
+ pr_warning("trace benchmark failed to create kernel thread\n");
+ return -ENOMEM;
+ }
+
+ return 0;
}
/*
@@ -182,6 +194,7 @@ void trace_benchmark_unreg(void)
return;
kthread_stop(bm_event_thread);
+ bm_event_thread = NULL;
strcpy(bm_str, "START");
bm_total = 0;
@@ -196,3 +209,12 @@ void trace_benchmark_unreg(void)
bm_avg = 0;
bm_stddev = 0;
}
+
+static __init int ok_to_run_trace_benchmark(void)
+{
+ ok_to_run = true;
+
+ return 0;
+}
+
+early_initcall(ok_to_run_trace_benchmark);
diff --git a/kernel/trace/trace_benchmark.h b/kernel/trace/trace_benchmark.h
index 3c1df1df4e29..ebdbfc2f2a64 100644
--- a/kernel/trace/trace_benchmark.h
+++ b/kernel/trace/trace_benchmark.h
@@ -6,7 +6,7 @@
#include <linux/tracepoint.h>
-extern void trace_benchmark_reg(void);
+extern int trace_benchmark_reg(void);
extern void trace_benchmark_unreg(void);
#define BENCHMARK_EVENT_STRLEN 128
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 3a2a73716a5b..75489de546b6 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -81,7 +81,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
entry->correct = val == expect;
if (!call_filter_check_discard(call, entry, buffer, event))
- __buffer_unlock_commit(buffer, event);
+ trace_buffer_unlock_commit_nostack(buffer, event);
out:
current->trace_recursion &= ~TRACE_BRANCH_BIT;
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
index d1cc37e78f99..eb7396b7e7c3 100644
--- a/kernel/trace/trace_entries.h
+++ b/kernel/trace/trace_entries.h
@@ -244,6 +244,21 @@ FTRACE_ENTRY(print, print_entry,
FILTER_OTHER
);
+FTRACE_ENTRY(raw_data, raw_data_entry,
+
+ TRACE_RAW_DATA,
+
+ F_STRUCT(
+ __field( unsigned int, id )
+ __dynamic_array( char, buf )
+ ),
+
+ F_printk("id:%04x %08x",
+ __entry->id, (int)__entry->buf[0]),
+
+ FILTER_OTHER
+);
+
FTRACE_ENTRY(bputs, bputs_entry,
TRACE_BPUTS,
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 03c0a48c3ac4..93116549a284 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -283,46 +283,6 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
}
EXPORT_SYMBOL_GPL(trace_event_buffer_reserve);
-static DEFINE_SPINLOCK(tracepoint_iter_lock);
-
-static void output_printk(struct trace_event_buffer *fbuffer)
-{
- struct trace_event_call *event_call;
- struct trace_event *event;
- unsigned long flags;
- struct trace_iterator *iter = tracepoint_print_iter;
-
- if (!iter)
- return;
-
- event_call = fbuffer->trace_file->event_call;
- if (!event_call || !event_call->event.funcs ||
- !event_call->event.funcs->trace)
- return;
-
- event = &fbuffer->trace_file->event_call->event;
-
- spin_lock_irqsave(&tracepoint_iter_lock, flags);
- trace_seq_init(&iter->seq);
- iter->ent = fbuffer->entry;
- event_call->event.funcs->trace(iter, 0, event);
- trace_seq_putc(&iter->seq, 0);
- printk("%s", iter->seq.buffer);
-
- spin_unlock_irqrestore(&tracepoint_iter_lock, flags);
-}
-
-void trace_event_buffer_commit(struct trace_event_buffer *fbuffer)
-{
- if (tracepoint_printk)
- output_printk(fbuffer);
-
- event_trigger_unlock_commit(fbuffer->trace_file, fbuffer->buffer,
- fbuffer->event, fbuffer->entry,
- fbuffer->flags, fbuffer->pc);
-}
-EXPORT_SYMBOL_GPL(trace_event_buffer_commit);
-
int trace_event_reg(struct trace_event_call *call,
enum trace_reg type, void *data)
{
@@ -742,6 +702,7 @@ __ftrace_set_clr_event_nolock(struct trace_array *tr, const char *match,
struct trace_event_call *call;
const char *name;
int ret = -EINVAL;
+ int eret = 0;
list_for_each_entry(file, &tr->events, list) {
@@ -765,9 +726,17 @@ __ftrace_set_clr_event_nolock(struct trace_array *tr, const char *match,
if (event && strcmp(event, name) != 0)
continue;
- ftrace_event_enable_disable(file, set);
+ ret = ftrace_event_enable_disable(file, set);
- ret = 0;
+ /*
+ * Save the first error and return that. Some events
+ * may still have been enabled, but let the user
+ * know that something went wrong.
+ */
+ if (ret && !eret)
+ eret = ret;
+
+ ret = eret;
}
return ret;
@@ -2843,20 +2812,32 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
return -ENOMEM;
}
+ entry = trace_create_file("enable", 0644, d_events,
+ tr, &ftrace_tr_enable_fops);
+ if (!entry) {
+ pr_warn("Could not create tracefs 'enable' entry\n");
+ return -ENOMEM;
+ }
+
+ /* There are not as crucial, just warn if they are not created */
+
entry = tracefs_create_file("set_event_pid", 0644, parent,
tr, &ftrace_set_event_pid_fops);
+ if (!entry)
+ pr_warn("Could not create tracefs 'set_event_pid' entry\n");
/* ring buffer internal formats */
- trace_create_file("header_page", 0444, d_events,
- ring_buffer_print_page_header,
- &ftrace_show_header_fops);
-
- trace_create_file("header_event", 0444, d_events,
- ring_buffer_print_entry_header,
- &ftrace_show_header_fops);
+ entry = trace_create_file("header_page", 0444, d_events,
+ ring_buffer_print_page_header,
+ &ftrace_show_header_fops);
+ if (!entry)
+ pr_warn("Could not create tracefs 'header_page' entry\n");
- trace_create_file("enable", 0644, d_events,
- tr, &ftrace_tr_enable_fops);
+ entry = trace_create_file("header_event", 0444, d_events,
+ ring_buffer_print_entry_header,
+ &ftrace_show_header_fops);
+ if (!entry)
+ pr_warn("Could not create tracefs 'header_event' entry\n");
tr->event_dir = d_events;
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 9daa9b3bc6d9..59a411ff60c7 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -108,12 +108,12 @@ static char *err_text[] = {
};
struct opstack_op {
- int op;
+ enum filter_op_ids op;
struct list_head list;
};
struct postfix_elt {
- int op;
+ enum filter_op_ids op;
char *operand;
struct list_head list;
};
@@ -145,34 +145,50 @@ struct pred_stack {
/* If not of not match is equal to not of not, then it is a match */
#define DEFINE_COMPARISON_PRED(type) \
-static int filter_pred_##type(struct filter_pred *pred, void *event) \
+static int filter_pred_LT_##type(struct filter_pred *pred, void *event) \
{ \
type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \
- int match = 0; \
- \
- switch (pred->op) { \
- case OP_LT: \
- match = (*addr < val); \
- break; \
- case OP_LE: \
- match = (*addr <= val); \
- break; \
- case OP_GT: \
- match = (*addr > val); \
- break; \
- case OP_GE: \
- match = (*addr >= val); \
- break; \
- case OP_BAND: \
- match = (*addr & val); \
- break; \
- default: \
- break; \
- } \
- \
+ int match = (*addr < val); \
return !!match == !pred->not; \
-}
+} \
+static int filter_pred_LE_##type(struct filter_pred *pred, void *event) \
+{ \
+ type *addr = (type *)(event + pred->offset); \
+ type val = (type)pred->val; \
+ int match = (*addr <= val); \
+ return !!match == !pred->not; \
+} \
+static int filter_pred_GT_##type(struct filter_pred *pred, void *event) \
+{ \
+ type *addr = (type *)(event + pred->offset); \
+ type val = (type)pred->val; \
+ int match = (*addr > val); \
+ return !!match == !pred->not; \
+} \
+static int filter_pred_GE_##type(struct filter_pred *pred, void *event) \
+{ \
+ type *addr = (type *)(event + pred->offset); \
+ type val = (type)pred->val; \
+ int match = (*addr >= val); \
+ return !!match == !pred->not; \
+} \
+static int filter_pred_BAND_##type(struct filter_pred *pred, void *event) \
+{ \
+ type *addr = (type *)(event + pred->offset); \
+ type val = (type)pred->val; \
+ int match = !!(*addr & val); \
+ return match == !pred->not; \
+} \
+static const filter_pred_fn_t pred_funcs_##type[] = { \
+ filter_pred_LT_##type, \
+ filter_pred_LE_##type, \
+ filter_pred_GT_##type, \
+ filter_pred_GE_##type, \
+ filter_pred_BAND_##type, \
+};
+
+#define PRED_FUNC_START OP_LT
#define DEFINE_EQUALITY_PRED(size) \
static int filter_pred_##size(struct filter_pred *pred, void *event) \
@@ -344,6 +360,12 @@ static int regex_match_end(char *str, struct regex *r, int len)
return 0;
}
+static int regex_match_glob(char *str, struct regex *r, int len __maybe_unused)
+{
+ if (glob_match(r->pattern, str))
+ return 1;
+ return 0;
+}
/**
* filter_parse_regex - parse a basic regex
* @buff: the raw regex
@@ -380,14 +402,20 @@ enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
if (!i) {
*search = buff + 1;
type = MATCH_END_ONLY;
- } else {
+ } else if (i == len - 1) {
if (type == MATCH_END_ONLY)
type = MATCH_MIDDLE_ONLY;
else
type = MATCH_FRONT_ONLY;
buff[i] = 0;
break;
+ } else { /* pattern continues, use full glob */
+ type = MATCH_GLOB;
+ break;
}
+ } else if (strchr("[?\\", buff[i])) {
+ type = MATCH_GLOB;
+ break;
}
}
@@ -420,6 +448,9 @@ static void filter_build_regex(struct filter_pred *pred)
case MATCH_END_ONLY:
r->match = regex_match_end;
break;
+ case MATCH_GLOB:
+ r->match = regex_match_glob;
+ break;
}
pred->not ^= not;
@@ -946,7 +977,7 @@ int filter_assign_type(const char *type)
return FILTER_OTHER;
}
-static bool is_legal_op(struct ftrace_event_field *field, int op)
+static bool is_legal_op(struct ftrace_event_field *field, enum filter_op_ids op)
{
if (is_string_field(field) &&
(op != OP_EQ && op != OP_NE && op != OP_GLOB))
@@ -957,8 +988,8 @@ static bool is_legal_op(struct ftrace_event_field *field, int op)
return true;
}
-static filter_pred_fn_t select_comparison_fn(int op, int field_size,
- int field_is_signed)
+static filter_pred_fn_t select_comparison_fn(enum filter_op_ids op,
+ int field_size, int field_is_signed)
{
filter_pred_fn_t fn = NULL;
@@ -967,33 +998,33 @@ static filter_pred_fn_t select_comparison_fn(int op, int field_size,
if (op == OP_EQ || op == OP_NE)
fn = filter_pred_64;
else if (field_is_signed)
- fn = filter_pred_s64;
+ fn = pred_funcs_s64[op - PRED_FUNC_START];
else
- fn = filter_pred_u64;
+ fn = pred_funcs_u64[op - PRED_FUNC_START];
break;
case 4:
if (op == OP_EQ || op == OP_NE)
fn = filter_pred_32;
else if (field_is_signed)
- fn = filter_pred_s32;
+ fn = pred_funcs_s32[op - PRED_FUNC_START];
else
- fn = filter_pred_u32;
+ fn = pred_funcs_u32[op - PRED_FUNC_START];
break;
case 2:
if (op == OP_EQ || op == OP_NE)
fn = filter_pred_16;
else if (field_is_signed)
- fn = filter_pred_s16;
+ fn = pred_funcs_s16[op - PRED_FUNC_START];
else
- fn = filter_pred_u16;
+ fn = pred_funcs_u16[op - PRED_FUNC_START];
break;
case 1:
if (op == OP_EQ || op == OP_NE)
fn = filter_pred_8;
else if (field_is_signed)
- fn = filter_pred_s8;
+ fn = pred_funcs_s8[op - PRED_FUNC_START];
else
- fn = filter_pred_u8;
+ fn = pred_funcs_u8[op - PRED_FUNC_START];
break;
}
@@ -1166,7 +1197,8 @@ static inline int append_operand_char(struct filter_parse_state *ps, char c)
return 0;
}
-static int filter_opstack_push(struct filter_parse_state *ps, int op)
+static int filter_opstack_push(struct filter_parse_state *ps,
+ enum filter_op_ids op)
{
struct opstack_op *opstack_op;
@@ -1200,7 +1232,7 @@ static int filter_opstack_top(struct filter_parse_state *ps)
static int filter_opstack_pop(struct filter_parse_state *ps)
{
struct opstack_op *opstack_op;
- int op;
+ enum filter_op_ids op;
if (filter_opstack_empty(ps))
return OP_NONE;
@@ -1245,7 +1277,7 @@ static int postfix_append_operand(struct filter_parse_state *ps, char *operand)
return 0;
}
-static int postfix_append_op(struct filter_parse_state *ps, int op)
+static int postfix_append_op(struct filter_parse_state *ps, enum filter_op_ids op)
{
struct postfix_elt *elt;
@@ -1275,8 +1307,8 @@ static void postfix_clear(struct filter_parse_state *ps)
static int filter_parse(struct filter_parse_state *ps)
{
+ enum filter_op_ids op, top_op;
int in_string = 0;
- int op, top_op;
char ch;
while ((ch = infix_next(ps))) {
@@ -1367,7 +1399,8 @@ parse_operand:
static struct filter_pred *create_pred(struct filter_parse_state *ps,
struct trace_event_call *call,
- int op, char *operand1, char *operand2)
+ enum filter_op_ids op,
+ char *operand1, char *operand2)
{
struct ftrace_event_field *field;
static struct filter_pred pred;
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 4e480e870474..d56123cdcc89 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -65,7 +65,7 @@ struct fgraph_data {
#define TRACE_GRAPH_INDENT 2
-static unsigned int max_depth;
+unsigned int fgraph_max_depth;
static struct tracer_opt trace_opts[] = {
/* Display overruns? (for self-debug purpose) */
@@ -358,7 +358,7 @@ int __trace_graph_entry(struct trace_array *tr,
entry = ring_buffer_event_data(event);
entry->graph_ent = *trace;
if (!call_filter_check_discard(call, entry, buffer, event))
- __buffer_unlock_commit(buffer, event);
+ trace_buffer_unlock_commit_nostack(buffer, event);
return 1;
}
@@ -384,10 +384,10 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
if (!ftrace_trace_task(tr))
return 0;
- /* trace it when it is-nested-in or is a function enabled. */
- if ((!(trace->depth || ftrace_graph_addr(trace->func)) ||
- ftrace_graph_ignore_irqs()) || (trace->depth < 0) ||
- (max_depth && trace->depth >= max_depth))
+ if (ftrace_graph_ignore_func(trace))
+ return 0;
+
+ if (ftrace_graph_ignore_irqs())
return 0;
/*
@@ -469,7 +469,7 @@ void __trace_graph_return(struct trace_array *tr,
entry = ring_buffer_event_data(event);
entry->ret = *trace;
if (!call_filter_check_discard(call, entry, buffer, event))
- __buffer_unlock_commit(buffer, event);
+ trace_buffer_unlock_commit_nostack(buffer, event);
}
void trace_graph_return(struct ftrace_graph_ret *trace)
@@ -842,6 +842,10 @@ print_graph_entry_leaf(struct trace_iterator *iter,
cpu_data = per_cpu_ptr(data->cpu_data, cpu);
+ /* If a graph tracer ignored set_graph_notrace */
+ if (call->depth < -1)
+ call->depth += FTRACE_NOTRACE_DEPTH;
+
/*
* Comments display at + 1 to depth. Since
* this is a leaf function, keep the comments
@@ -850,7 +854,8 @@ print_graph_entry_leaf(struct trace_iterator *iter,
cpu_data->depth = call->depth - 1;
/* No need to keep this function around for this depth */
- if (call->depth < FTRACE_RETFUNC_DEPTH)
+ if (call->depth < FTRACE_RETFUNC_DEPTH &&
+ !WARN_ON_ONCE(call->depth < 0))
cpu_data->enter_funcs[call->depth] = 0;
}
@@ -880,11 +885,16 @@ print_graph_entry_nested(struct trace_iterator *iter,
struct fgraph_cpu_data *cpu_data;
int cpu = iter->cpu;
+ /* If a graph tracer ignored set_graph_notrace */
+ if (call->depth < -1)
+ call->depth += FTRACE_NOTRACE_DEPTH;
+
cpu_data = per_cpu_ptr(data->cpu_data, cpu);
cpu_data->depth = call->depth;
/* Save this function pointer to see if the exit matches */
- if (call->depth < FTRACE_RETFUNC_DEPTH)
+ if (call->depth < FTRACE_RETFUNC_DEPTH &&
+ !WARN_ON_ONCE(call->depth < 0))
cpu_data->enter_funcs[call->depth] = call->func;
}
@@ -1114,7 +1124,8 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
*/
cpu_data->depth = trace->depth - 1;
- if (trace->depth < FTRACE_RETFUNC_DEPTH) {
+ if (trace->depth < FTRACE_RETFUNC_DEPTH &&
+ !WARN_ON_ONCE(trace->depth < 0)) {
if (cpu_data->enter_funcs[trace->depth] != trace->func)
func_match = 0;
cpu_data->enter_funcs[trace->depth] = 0;
@@ -1489,7 +1500,7 @@ graph_depth_write(struct file *filp, const char __user *ubuf, size_t cnt,
if (ret)
return ret;
- max_depth = val;
+ fgraph_max_depth = val;
*ppos += cnt;
@@ -1503,7 +1514,7 @@ graph_depth_read(struct file *filp, char __user *ubuf, size_t cnt,
char buf[15]; /* More than enough to hold UINT_MAX + "\n"*/
int n;
- n = sprintf(buf, "%d\n", max_depth);
+ n = sprintf(buf, "%d\n", fgraph_max_depth);
return simple_read_from_buffer(ubuf, cnt, ppos, buf, n);
}
diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c
index b97286c48735..775569ec50d0 100644
--- a/kernel/trace/trace_hwlat.c
+++ b/kernel/trace/trace_hwlat.c
@@ -127,7 +127,7 @@ static void trace_hwlat_sample(struct hwlat_sample *sample)
entry->nmi_count = sample->nmi_count;
if (!call_filter_check_discard(call, entry, buffer, event))
- __buffer_unlock_commit(buffer, event);
+ trace_buffer_unlock_commit_nostack(buffer, event);
}
/* Macros to encapsulate the time capturing infrastructure */
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 03cdff84d026..86654d7e1afe 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -175,6 +175,18 @@ static int irqsoff_graph_entry(struct ftrace_graph_ent *trace)
int ret;
int pc;
+ if (ftrace_graph_ignore_func(trace))
+ return 0;
+ /*
+ * Do not trace a function if it's filtered by set_graph_notrace.
+ * Make the index of ret stack negative to indicate that it should
+ * ignore further functions. But it needs its own ret stack entry
+ * to recover the original index in order to continue tracing after
+ * returning from the function.
+ */
+ if (ftrace_graph_notrace_addr(trace->func))
+ return 1;
+
if (!func_prolog_dec(tr, &data, &flags))
return 0;
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index eb6c9f1d3a93..a133ecd741e4 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -73,6 +73,17 @@ static nokprobe_inline bool trace_kprobe_is_on_module(struct trace_kprobe *tk)
return !!strchr(trace_kprobe_symbol(tk), ':');
}
+static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
+{
+ unsigned long nhit = 0;
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ nhit += *per_cpu_ptr(tk->nhit, cpu);
+
+ return nhit;
+}
+
static int register_kprobe_event(struct trace_kprobe *tk);
static int unregister_kprobe_event(struct trace_kprobe *tk);
@@ -882,14 +893,10 @@ static const struct file_operations kprobe_events_ops = {
static int probes_profile_seq_show(struct seq_file *m, void *v)
{
struct trace_kprobe *tk = v;
- unsigned long nhit = 0;
- int cpu;
-
- for_each_possible_cpu(cpu)
- nhit += *per_cpu_ptr(tk->nhit, cpu);
seq_printf(m, " %-44s %15lu %15lu\n",
- trace_event_name(&tk->tp.call), nhit,
+ trace_event_name(&tk->tp.call),
+ trace_kprobe_nhit(tk),
tk->rp.kp.nmissed);
return 0;
@@ -1354,18 +1361,18 @@ fs_initcall(init_kprobe_trace);
#ifdef CONFIG_FTRACE_STARTUP_TEST
-
/*
* The "__used" keeps gcc from removing the function symbol
- * from the kallsyms table.
+ * from the kallsyms table. 'noinline' makes sure that there
+ * isn't an inlined version used by the test method below
*/
-static __used int kprobe_trace_selftest_target(int a1, int a2, int a3,
- int a4, int a5, int a6)
+static __used __init noinline int
+kprobe_trace_selftest_target(int a1, int a2, int a3, int a4, int a5, int a6)
{
return a1 + a2 + a3 + a4 + a5 + a6;
}
-static struct trace_event_file *
+static struct __init trace_event_file *
find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
{
struct trace_event_file *file;
@@ -1443,12 +1450,25 @@ static __init int kprobe_trace_self_tests_init(void)
ret = target(1, 2, 3, 4, 5, 6);
+ /*
+ * Not expecting an error here, the check is only to prevent the
+ * optimizer from removing the call to target() as otherwise there
+ * are no side-effects and the call is never performed.
+ */
+ if (ret != 21)
+ warn++;
+
/* Disable trace points before removing it */
tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
if (WARN_ON_ONCE(tk == NULL)) {
pr_warn("error on getting test probe.\n");
warn++;
} else {
+ if (trace_kprobe_nhit(tk) != 1) {
+ pr_warn("incorrect number of testprobe hits\n");
+ warn++;
+ }
+
file = find_trace_probe_file(tk, top_trace_array());
if (WARN_ON_ONCE(file == NULL)) {
pr_warn("error on getting probe file.\n");
@@ -1462,6 +1482,11 @@ static __init int kprobe_trace_self_tests_init(void)
pr_warn("error on getting 2nd test probe.\n");
warn++;
} else {
+ if (trace_kprobe_nhit(tk) != 1) {
+ pr_warn("incorrect number of testprobe2 hits\n");
+ warn++;
+ }
+
file = find_trace_probe_file(tk, top_trace_array());
if (WARN_ON_ONCE(file == NULL)) {
pr_warn("error on getting probe file.\n");
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 3fc20422c166..5d33a7352919 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -1288,6 +1288,35 @@ static struct trace_event trace_print_event = {
.funcs = &trace_print_funcs,
};
+static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags,
+ struct trace_event *event)
+{
+ struct raw_data_entry *field;
+ int i;
+
+ trace_assign_type(field, iter->ent);
+
+ trace_seq_printf(&iter->seq, "# %x buf:", field->id);
+
+ for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++)
+ trace_seq_printf(&iter->seq, " %02x",
+ (unsigned char)field->buf[i]);
+
+ trace_seq_putc(&iter->seq, '\n');
+
+ return trace_handle_return(&iter->seq);
+}
+
+static struct trace_event_functions trace_raw_data_funcs = {
+ .trace = trace_raw_data,
+ .raw = trace_raw_data,
+};
+
+static struct trace_event trace_raw_data_event = {
+ .type = TRACE_RAW_DATA,
+ .funcs = &trace_raw_data_funcs,
+};
+
static struct trace_event *events[] __initdata = {
&trace_fn_event,
@@ -1299,6 +1328,7 @@ static struct trace_event *events[] __initdata = {
&trace_bprint_event,
&trace_print_event,
&trace_hwlat_event,
+ &trace_raw_data_event,
NULL
};
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 9d4399b553a3..5d0bb025bb21 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -239,6 +239,18 @@ static int wakeup_graph_entry(struct ftrace_graph_ent *trace)
unsigned long flags;
int pc, ret = 0;
+ if (ftrace_graph_ignore_func(trace))
+ return 0;
+ /*
+ * Do not trace a function if it's filtered by set_graph_notrace.
+ * Make the index of ret stack negative to indicate that it should
+ * ignore further functions. But it needs its own ret stack entry
+ * to recover the original index in order to continue tracing after
+ * returning from the function.
+ */
+ if (ftrace_graph_notrace_addr(trace->func))
+ return 1;
+
if (!func_prolog_preempt_disable(tr, &data, &pc))
return 0;
@@ -790,6 +802,7 @@ static struct tracer wakeup_dl_tracer __read_mostly =
#endif
.open = wakeup_trace_open,
.close = wakeup_trace_close,
+ .allow_instances = true,
.use_max_tr = true,
};
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index d0639d917899..1f9a31f934a4 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -194,9 +194,13 @@ static int tracepoint_add_func(struct tracepoint *tp,
struct tracepoint_func *func, int prio)
{
struct tracepoint_func *old, *tp_funcs;
+ int ret;
- if (tp->regfunc && !static_key_enabled(&tp->key))
- tp->regfunc();
+ if (tp->regfunc && !static_key_enabled(&tp->key)) {
+ ret = tp->regfunc();
+ if (ret < 0)
+ return ret;
+ }
tp_funcs = rcu_dereference_protected(tp->funcs,
lockdep_is_held(&tracepoints_mutex));
@@ -529,7 +533,7 @@ EXPORT_SYMBOL_GPL(for_each_kernel_tracepoint);
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
static int sys_tracepoint_refcount;
-void syscall_regfunc(void)
+int syscall_regfunc(void)
{
struct task_struct *p, *t;
@@ -541,6 +545,8 @@ void syscall_regfunc(void)
read_unlock(&tasklist_lock);
}
sys_tracepoint_refcount++;
+
+ return 0;
}
void syscall_unregfunc(void)
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 0019aca0f328..6f382e07de77 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -31,7 +31,6 @@
#include <linux/percpu.h>
#include <linux/slab.h>
#include <linux/kmemleak.h>
-#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/string.h>
#include <linux/bitops.h>
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 345f09059e9f..d5f311767157 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -100,11 +100,14 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
trans->cm_connect_complete(conn, event);
break;
+ case RDMA_CM_EVENT_REJECTED:
+ rdsdebug("Connection rejected: %s\n",
+ rdma_reject_msg(cm_id, event->status));
+ /* FALLTHROUGH */
case RDMA_CM_EVENT_ADDR_ERROR:
case RDMA_CM_EVENT_ROUTE_ERROR:
case RDMA_CM_EVENT_CONNECT_ERROR:
case RDMA_CM_EVENT_UNREACHABLE:
- case RDMA_CM_EVENT_REJECTED:
case RDMA_CM_EVENT_DEVICE_REMOVAL:
case RDMA_CM_EVENT_ADDR_CHANGE:
if (conn)
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
index 880a7d1d27d2..30e282d33d4d 100644
--- a/samples/trace_events/trace-events-sample.c
+++ b/samples/trace_events/trace-events-sample.c
@@ -79,7 +79,7 @@ static int simple_thread_fn(void *arg)
static DEFINE_MUTEX(thread_mutex);
-void foo_bar_reg(void)
+int foo_bar_reg(void)
{
pr_info("Starting thread for foo_bar_fn\n");
/*
@@ -90,6 +90,7 @@ void foo_bar_reg(void)
mutex_lock(&thread_mutex);
simple_tsk_fn = kthread_run(simple_thread_fn, NULL, "event-sample-fn");
mutex_unlock(&thread_mutex);
+ return 0;
}
void foo_bar_unreg(void)
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
index d6b75bb495b3..76a75ab7a608 100644
--- a/samples/trace_events/trace-events-sample.h
+++ b/samples/trace_events/trace-events-sample.h
@@ -354,7 +354,7 @@ TRACE_EVENT_CONDITION(foo_bar_with_cond,
TP_printk("foo %s %d", __get_str(foo), __entry->bar)
);
-void foo_bar_reg(void);
+int foo_bar_reg(void);
void foo_bar_unreg(void);
/*
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index bd8349759095..5a6b39a29b7a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2371,6 +2371,7 @@ static void write_dump(const char *fname)
}
}
write_if_changed(&buf, fname);
+ free(buf.p);
}
struct ext_sym_list {
@@ -2496,6 +2497,7 @@ int main(int argc, char **argv)
"Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
}
}
+ free(buf.p);
return err;
}
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 5423a58d1b06..aeb34223167c 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -213,6 +213,59 @@ static int make_nop_x86(void *map, size_t const offset)
return 0;
}
+static unsigned char ideal_nop4_arm_le[4] = { 0x00, 0x00, 0xa0, 0xe1 }; /* mov r0, r0 */
+static unsigned char ideal_nop4_arm_be[4] = { 0xe1, 0xa0, 0x00, 0x00 }; /* mov r0, r0 */
+static unsigned char *ideal_nop4_arm;
+
+static unsigned char bl_mcount_arm_le[4] = { 0xfe, 0xff, 0xff, 0xeb }; /* bl */
+static unsigned char bl_mcount_arm_be[4] = { 0xeb, 0xff, 0xff, 0xfe }; /* bl */
+static unsigned char *bl_mcount_arm;
+
+static unsigned char push_arm_le[4] = { 0x04, 0xe0, 0x2d, 0xe5 }; /* push {lr} */
+static unsigned char push_arm_be[4] = { 0xe5, 0x2d, 0xe0, 0x04 }; /* push {lr} */
+static unsigned char *push_arm;
+
+static unsigned char ideal_nop2_thumb_le[2] = { 0x00, 0xbf }; /* nop */
+static unsigned char ideal_nop2_thumb_be[2] = { 0xbf, 0x00 }; /* nop */
+static unsigned char *ideal_nop2_thumb;
+
+static unsigned char push_bl_mcount_thumb_le[6] = { 0x00, 0xb5, 0xff, 0xf7, 0xfe, 0xff }; /* push {lr}, bl */
+static unsigned char push_bl_mcount_thumb_be[6] = { 0xb5, 0x00, 0xf7, 0xff, 0xff, 0xfe }; /* push {lr}, bl */
+static unsigned char *push_bl_mcount_thumb;
+
+static int make_nop_arm(void *map, size_t const offset)
+{
+ char *ptr;
+ int cnt = 1;
+ int nop_size;
+ size_t off = offset;
+
+ ptr = map + offset;
+ if (memcmp(ptr, bl_mcount_arm, 4) == 0) {
+ if (memcmp(ptr - 4, push_arm, 4) == 0) {
+ off -= 4;
+ cnt = 2;
+ }
+ ideal_nop = ideal_nop4_arm;
+ nop_size = 4;
+ } else if (memcmp(ptr - 2, push_bl_mcount_thumb, 6) == 0) {
+ cnt = 3;
+ nop_size = 2;
+ off -= 2;
+ ideal_nop = ideal_nop2_thumb;
+ } else
+ return -1;
+
+ /* Convert to nop */
+ ulseek(fd_map, off, SEEK_SET);
+
+ do {
+ uwrite(fd_map, ideal_nop, nop_size);
+ } while (--cnt > 0);
+
+ return 0;
+}
+
static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5};
static int make_nop_arm64(void *map, size_t const offset)
{
@@ -430,6 +483,11 @@ do_file(char const *const fname)
w2 = w2rev;
w8 = w8rev;
}
+ ideal_nop4_arm = ideal_nop4_arm_le;
+ bl_mcount_arm = bl_mcount_arm_le;
+ push_arm = push_arm_le;
+ ideal_nop2_thumb = ideal_nop2_thumb_le;
+ push_bl_mcount_thumb = push_bl_mcount_thumb_le;
break;
case ELFDATA2MSB:
if (*(unsigned char const *)&endian != 0) {
@@ -438,6 +496,11 @@ do_file(char const *const fname)
w2 = w2rev;
w8 = w8rev;
}
+ ideal_nop4_arm = ideal_nop4_arm_be;
+ bl_mcount_arm = bl_mcount_arm_be;
+ push_arm = push_arm_be;
+ ideal_nop2_thumb = ideal_nop2_thumb_be;
+ push_bl_mcount_thumb = push_bl_mcount_thumb_be;
break;
} /* end switch */
if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0
@@ -463,6 +526,8 @@ do_file(char const *const fname)
break;
case EM_ARM: reltype = R_ARM_ABS32;
altmcount = "__gnu_mcount_nc";
+ make_nop = make_nop_arm;
+ rel_type_nop = R_ARM_NONE;
break;
case EM_AARCH64:
reltype = R_AARCH64_ABS64;
diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 53af6dc3e6c1..19ec468b1168 100644
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -267,7 +267,7 @@ int main(int argc, char **argv)
}
x509_name = argv[2];
module_name = argv[3];
- if (argc == 5) {
+ if (argc == 5 && strcmp(argv[3], argv[4]) != 0) {
dest_name = argv[4];
replace_orig = false;
} else {
diff --git a/tools/testing/radix-tree/linux/cpu.h b/tools/testing/radix-tree/linux/cpu.h
index 7cf412103205..a45530d78107 100644
--- a/tools/testing/radix-tree/linux/cpu.h
+++ b/tools/testing/radix-tree/linux/cpu.h
@@ -1,21 +1 @@
-
-#define hotcpu_notifier(a, b)
-
-#define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */
-#define CPU_UP_PREPARE 0x0003 /* CPU (unsigned)v coming up */
-#define CPU_UP_CANCELED 0x0004 /* CPU (unsigned)v NOT coming up */
-#define CPU_DOWN_PREPARE 0x0005 /* CPU (unsigned)v going down */
-#define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */
-#define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */
-#define CPU_POST_DEAD 0x0009 /* CPU (unsigned)v dead, cpu_hotplug
- * lock is dropped */
-#define CPU_BROKEN 0x000C /* CPU (unsigned)v did not die properly,
- * perhaps due to preemption. */
-#define CPU_TASKS_FROZEN 0x0010
-
-#define CPU_ONLINE_FROZEN (CPU_ONLINE | CPU_TASKS_FROZEN)
-#define CPU_UP_PREPARE_FROZEN (CPU_UP_PREPARE | CPU_TASKS_FROZEN)
-#define CPU_UP_CANCELED_FROZEN (CPU_UP_CANCELED | CPU_TASKS_FROZEN)
-#define CPU_DOWN_PREPARE_FROZEN (CPU_DOWN_PREPARE | CPU_TASKS_FROZEN)
-#define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN)
-#define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN)
+#define cpuhp_setup_state_nocalls(a, b, c, d) (0)
diff --git a/tools/testing/radix-tree/linux/notifier.h b/tools/testing/radix-tree/linux/notifier.h
deleted file mode 100644
index 70e4797d5a46..000000000000
--- a/tools/testing/radix-tree/linux/notifier.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _NOTIFIER_H
-#define _NOTIFIER_H
-
-struct notifier_block;
-
-#define NOTIFY_OK 0x0001 /* Suits me */
-
-#endif
diff --git a/tools/testing/selftests/.gitignore b/tools/testing/selftests/.gitignore
new file mode 100644
index 000000000000..f0600d20ce7d
--- /dev/null
+++ b/tools/testing/selftests/.gitignore
@@ -0,0 +1 @@
+kselftest
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index a3144a3de3a8..71b05891a6a1 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += exec
TARGETS += firmware
TARGETS += ftrace
TARGETS += futex
+TARGETS += gpio
TARGETS += ipc
TARGETS += kcmp
TARGETS += lib
@@ -24,6 +25,7 @@ TARGETS += seccomp
TARGETS += sigaltstack
TARGETS += size
TARGETS += static_keys
+TARGETS += sync
TARGETS += sysctl
ifneq (1, $(quicktest))
TARGETS += timers
diff --git a/tools/testing/selftests/drivers/gpu/i915.sh b/tools/testing/selftests/drivers/gpu/i915.sh
new file mode 100755
index 000000000000..d407f0fa1e3a
--- /dev/null
+++ b/tools/testing/selftests/drivers/gpu/i915.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Runs hardware independent tests for i915 (drivers/gpu/drm/i915)
+
+if ! /sbin/modprobe -q -r i915; then
+ echo "drivers/gpu/i915: [SKIP]"
+ exit 77
+fi
+
+if /sbin/modprobe -q i915 mock_selftests=-1; then
+ echo "drivers/gpu/i915: ok"
+else
+ echo "drivers/gpu/i915: [FAIL]"
+ exit 1
+fi
diff --git a/tools/testing/selftests/ftrace/.gitignore b/tools/testing/selftests/ftrace/.gitignore
new file mode 100644
index 000000000000..98d8a5a63049
--- /dev/null
+++ b/tools/testing/selftests/ftrace/.gitignore
@@ -0,0 +1 @@
+logs
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 4c6a0bf8ba79..52e3c4df28d6 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -13,7 +13,8 @@ echo "Usage: ftracetest [options] [testcase(s)] [testcase-directory(s)]"
echo " Options:"
echo " -h|--help Show help message"
echo " -k|--keep Keep passed test logs"
-echo " -v|--verbose Show all stdout messages in testcases"
+echo " -v|--verbose Increase verbosity of test messages"
+echo " -vv Alias of -v -v (Show all results in stdout)"
echo " -d|--debug Debug mode (trace all shell commands)"
exit $1
}
@@ -54,8 +55,9 @@ parse_opts() { # opts
KEEP_LOG=1
shift 1
;;
- --verbose|-v)
- VERBOSE=1
+ --verbose|-v|-vv)
+ VERBOSE=$((VERBOSE + 1))
+ [ $1 == '-vv' ] && VERBOSE=$((VERBOSE + 1))
shift 1
;;
--debug|-d)
@@ -228,7 +230,7 @@ trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL
__run_test() { # testfile
# setup PID and PPID, $$ is not updated.
- (cd $TRACING_DIR; read PID _ < /proc/self/stat ; set -e; set -x; . $1)
+ (cd $TRACING_DIR; read PID _ < /proc/self/stat; set -e; set -x; initialize_ftrace; . $1)
[ $? -ne 0 ] && kill -s $SIG_FAIL $SIG_PID
}
@@ -236,10 +238,11 @@ __run_test() { # testfile
run_test() { # testfile
local testname=`basename $1`
local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX`
+ export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX`
testcase $1
echo "execute: "$1 > $testlog
SIG_RESULT=0
- if [ $VERBOSE -ne 0 ]; then
+ if [ $VERBOSE -ge 2 ]; then
__run_test $1 2>> $testlog | tee -a $testlog
else
__run_test $1 >> $testlog 2>&1
@@ -249,9 +252,10 @@ run_test() { # testfile
# Remove test log if the test was done as it was expected.
[ $KEEP_LOG -eq 0 ] && rm $testlog
else
- catlog $testlog
+ [ $VERBOSE -ge 1 ] && catlog $testlog
TOTAL_RESULT=1
fi
+ rm -rf $TMPDIR
}
# load in the helper functions
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc
new file mode 100644
index 000000000000..9dcd0ca1f49c
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc
@@ -0,0 +1,49 @@
+#!/bin/sh
+# description: ftrace - function glob filters
+
+# Make sure that function glob matching filter works.
+
+if ! grep -q function available_tracers; then
+ echo "no function tracer configured"
+ exit_unsupported
+fi
+
+disable_tracing
+clear_trace
+
+# filter by ?, schedule is always good
+if ! echo "sch?dule" > set_ftrace_filter; then
+ # test for powerpc 64
+ if ! echo ".sch?dule" > set_ftrace_filter; then
+ fail "can not enable schedule filter"
+ fi
+ cat set_ftrace_filter | grep '^.schedule$'
+else
+ cat set_ftrace_filter | grep '^schedule$'
+fi
+
+ftrace_filter_check() { # glob grep
+ echo "$1" > set_ftrace_filter
+ cut -f1 -d" " set_ftrace_filter > $TMPDIR/actual
+ cut -f1 -d" " available_filter_functions | grep "$2" > $TMPDIR/expected
+ DIFF=`diff $TMPDIR/actual $TMPDIR/expected`
+ test -z "$DIFF"
+}
+
+# filter by *, front match
+ftrace_filter_check '*schedule' '^.*schedule$'
+
+# filter by *, middle match
+ftrace_filter_check '*schedule*' '^.*schedule.*$'
+
+# filter by *, end match
+ftrace_filter_check 'schedule*' '^schedule.*$'
+
+# filter by *, both side match
+ftrace_filter_check 'sch*ule' '^sch.*ule$'
+
+# filter by char class.
+ftrace_filter_check '[Ss]y[Ss]_*' '^[Ss]y[Ss]_.*$'
+
+echo > set_ftrace_filter
+enable_tracing
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions
index c37262f6c269..91de1a8e4f19 100644
--- a/tools/testing/selftests/ftrace/test.d/functions
+++ b/tools/testing/selftests/ftrace/test.d/functions
@@ -23,3 +23,31 @@ reset_trigger() { # reset all current setting triggers
done
}
+reset_events_filter() { # reset all current setting filters
+ grep -v ^none events/*/*/filter |
+ while read line; do
+ echo 0 > `echo $line | cut -f1 -d:`
+ done
+}
+
+disable_events() {
+ echo 0 > events/enable
+}
+
+initialize_ftrace() { # Reset ftrace to initial-state
+# As the initial state, ftrace will be set to nop tracer,
+# no events, no triggers, no filters, no function filters,
+# no probes, and tracing on.
+ disable_tracing
+ reset_tracer
+ reset_trigger
+ reset_events_filter
+ disable_events
+ echo > set_event_pid # event tracer is always on
+ [ -f set_ftrace_filter ] && echo | tee set_ftrace_*
+ [ -f set_graph_function ] && echo | tee set_graph_*
+ [ -f stack_trace_filter ] && echo > stack_trace_filter
+ [ -f kprobe_events ] && echo > kprobe_events
+ [ -f uprobe_events ] && echo > uprobe_events
+ enable_tracing
+}
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
new file mode 100644
index 000000000000..0a78705b43b2
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
@@ -0,0 +1,37 @@
+#!/bin/sh
+# description: Kprobes event arguments with types
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue
+
+echo 0 > events/enable
+echo > kprobe_events
+enable_tracing
+
+echo 'p:testprobe _do_fork $stack0:s32 $stack0:u32 $stack0:x32 $stack0:b8@4/32' > kprobe_events
+grep testprobe kprobe_events
+test -d events/kprobes/testprobe
+
+echo 1 > events/kprobes/testprobe/enable
+( echo "forked")
+echo 0 > events/kprobes/testprobe/enable
+ARGS=`tail -n 1 trace | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'`
+
+check_types() {
+ X1=`printf "%x" $1 | tail -c 8`
+ X2=`printf "%x" $2`
+ X3=`printf "%x" $3`
+ test $X1 = $X2
+ test $X2 = $X3
+ test 0x$X3 = $3
+
+ B4=`printf "%x" $4`
+ B3=`echo -n $X3 | tail -c 3 | head -c 2`
+ test $B3 = $B4
+}
+check_types $ARGS
+
+echo "-:testprobe" >> kprobe_events
+clear_trace
+test -d events/kprobes/testprobe && exit 1 || exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
index 0bf5085281f3..400e98b64948 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
@@ -56,7 +56,7 @@ echo "Test histogram with syscall modifier"
echo 'hist:keys=id.syscall' > events/raw_syscalls/sys_exit/trigger
for i in `seq 1 10` ; do ( echo "forked" > /dev/null); done
-grep "id: sys_" events/raw_syscalls/sys_exit/hist > /dev/null || \
+grep "id: \(unknown_\|sys_\)" events/raw_syscalls/sys_exit/hist > /dev/null || \
fail "syscall modifier on raw_syscalls/sys_exit did not work"
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
index f84b80d551a2..ed94f0c4e0e4 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
@@ -23,6 +23,11 @@ if [ ! -f events/sched/sched_process_fork/trigger ]; then
exit_unsupported
fi
+if [ ! -f snapshot ]; then
+ echo "snapshot is not supported"
+ exit_unsupported
+fi
+
reset_tracer
do_reset
diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile
new file mode 100644
index 000000000000..205e4d10e085
--- /dev/null
+++ b/tools/testing/selftests/gpio/Makefile
@@ -0,0 +1,23 @@
+
+TEST_PROGS := gpio-mockup.sh
+TEST_FILES := gpio-mockup-sysfs.sh $(BINARIES)
+BINARIES := gpio-mockup-chardev
+
+include ../lib.mk
+
+all: $(BINARIES)
+
+clean:
+ $(RM) $(BINARIES)
+
+CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/
+LDLIBS += -lmount -I/usr/include/libmount
+
+$(BINARIES): ../../../gpio/gpio-utils.o ../../../../usr/include/linux/gpio.h
+
+../../../gpio/gpio-utils.o:
+ make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C ../../../gpio
+
+../../../../usr/include/linux/gpio.h:
+ make -C ../../../.. headers_install INSTALL_HDR_PATH=$(shell pwd)/../../../../usr/
+
diff --git a/tools/testing/selftests/gpio/gpio-mockup-chardev.c b/tools/testing/selftests/gpio/gpio-mockup-chardev.c
new file mode 100644
index 000000000000..667e916fa7cc
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio-mockup-chardev.c
@@ -0,0 +1,324 @@
+/*
+ * GPIO chardev test helper
+ *
+ * Copyright (C) 2016 Bamvor Jian Zhang
+ *
+ * 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 _GNU_SOURCE
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <libmount.h>
+#include <err.h>
+#include <dirent.h>
+#include <linux/gpio.h>
+#include "../../../gpio/gpio-utils.h"
+
+#define CONSUMER "gpio-selftest"
+#define GC_NUM 10
+enum direction {
+ OUT,
+ IN
+};
+
+static int get_debugfs(char **path)
+{
+ struct libmnt_context *cxt;
+ struct libmnt_table *tb;
+ struct libmnt_iter *itr = NULL;
+ struct libmnt_fs *fs;
+ int found = 0;
+
+ cxt = mnt_new_context();
+ if (!cxt)
+ err(EXIT_FAILURE, "libmount context allocation failed");
+
+ itr = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!itr)
+ err(EXIT_FAILURE, "failed to initialize libmount iterator");
+
+ if (mnt_context_get_mtab(cxt, &tb))
+ err(EXIT_FAILURE, "failed to read mtab");
+
+ while (mnt_table_next_fs(tb, itr, &fs) == 0) {
+ const char *type = mnt_fs_get_fstype(fs);
+
+ if (!strcmp(type, "debugfs")) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ asprintf(path, "%s/gpio", mnt_fs_get_target(fs));
+
+ mnt_free_iter(itr);
+ mnt_free_context(cxt);
+
+ if (!found)
+ return -1;
+
+ return 0;
+}
+
+static int gpio_debugfs_get(const char *consumer, int *dir, int *value)
+{
+ char *debugfs;
+ FILE *f;
+ char *line = NULL;
+ size_t len = 0;
+ char *cur;
+ int found = 0;
+
+ if (get_debugfs(&debugfs) != 0)
+ err(EXIT_FAILURE, "debugfs is not mounted");
+
+ f = fopen(debugfs, "r");
+ if (!f)
+ err(EXIT_FAILURE, "read from gpio debugfs failed");
+
+ /*
+ * gpio-2 ( |gpio-selftest ) in lo
+ */
+ while (getline(&line, &len, f) != -1) {
+ cur = strstr(line, consumer);
+ if (cur == NULL)
+ continue;
+
+ cur = strchr(line, ')');
+ if (!cur)
+ continue;
+
+ cur += 2;
+ if (!strncmp(cur, "out", 3)) {
+ *dir = OUT;
+ cur += 4;
+ } else if (!strncmp(cur, "in", 2)) {
+ *dir = IN;
+ cur += 4;
+ }
+
+ if (!strncmp(cur, "hi", 2))
+ *value = 1;
+ else if (!strncmp(cur, "lo", 2))
+ *value = 0;
+
+ found = 1;
+ break;
+ }
+ free(debugfs);
+ fclose(f);
+ free(line);
+
+ if (!found)
+ return -1;
+
+ return 0;
+}
+
+static struct gpiochip_info *list_gpiochip(const char *gpiochip_name, int *ret)
+{
+ struct gpiochip_info *cinfo;
+ struct gpiochip_info *current;
+ const struct dirent *ent;
+ DIR *dp;
+ char *chrdev_name;
+ int fd;
+ int i = 0;
+
+ cinfo = calloc(sizeof(struct gpiochip_info) * 4, GC_NUM + 1);
+ if (!cinfo)
+ err(EXIT_FAILURE, "gpiochip_info allocation failed");
+
+ current = cinfo;
+ dp = opendir("/dev");
+ if (!dp) {
+ *ret = -errno;
+ goto error_out;
+ } else {
+ *ret = 0;
+ }
+
+ while (ent = readdir(dp), ent) {
+ if (check_prefix(ent->d_name, "gpiochip")) {
+ *ret = asprintf(&chrdev_name, "/dev/%s", ent->d_name);
+ if (*ret < 0)
+ goto error_out;
+
+ fd = open(chrdev_name, 0);
+ if (fd == -1) {
+ *ret = -errno;
+ fprintf(stderr, "Failed to open %s\n",
+ chrdev_name);
+ goto error_close_dir;
+ }
+ *ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, current);
+ if (*ret == -1) {
+ perror("Failed to issue CHIPINFO IOCTL\n");
+ goto error_close_dir;
+ }
+ close(fd);
+ if (strcmp(current->label, gpiochip_name) == 0
+ || check_prefix(current->label, gpiochip_name)) {
+ *ret = 0;
+ current++;
+ i++;
+ }
+ }
+ }
+
+ if ((!*ret && i == 0) || *ret < 0) {
+ free(cinfo);
+ cinfo = NULL;
+ }
+ if (!*ret && i > 0) {
+ cinfo = realloc(cinfo, sizeof(struct gpiochip_info) * 4 * i);
+ *ret = i;
+ }
+
+error_close_dir:
+ closedir(dp);
+error_out:
+ if (*ret < 0)
+ err(EXIT_FAILURE, "list gpiochip failed: %s", strerror(*ret));
+
+ return cinfo;
+}
+
+int gpio_pin_test(struct gpiochip_info *cinfo, int line, int flag, int value)
+{
+ struct gpiohandle_data data;
+ unsigned int lines[] = {line};
+ int fd;
+ int debugfs_dir = IN;
+ int debugfs_value = 0;
+ int ret;
+
+ data.values[0] = value;
+ ret = gpiotools_request_linehandle(cinfo->name, lines, 1, flag, &data,
+ CONSUMER);
+ if (ret < 0)
+ goto fail_out;
+ else
+ fd = ret;
+
+ ret = gpio_debugfs_get(CONSUMER, &debugfs_dir, &debugfs_value);
+ if (ret) {
+ ret = -EINVAL;
+ goto fail_out;
+ }
+ if (flag & GPIOHANDLE_REQUEST_INPUT) {
+ if (debugfs_dir != IN) {
+ errno = -EINVAL;
+ ret = -errno;
+ }
+ } else if (flag & GPIOHANDLE_REQUEST_OUTPUT) {
+ if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW)
+ debugfs_value = !debugfs_value;
+
+ if (!(debugfs_dir == OUT && value == debugfs_value))
+ errno = -EINVAL;
+ ret = -errno;
+
+ }
+ gpiotools_release_linehandle(fd);
+
+fail_out:
+ if (ret)
+ err(EXIT_FAILURE, "gpio<%s> line<%d> test flag<0x%x> value<%d>",
+ cinfo->name, line, flag, value);
+
+ return ret;
+}
+
+void gpio_pin_tests(struct gpiochip_info *cinfo, unsigned int line)
+{
+ printf("line<%d>", line);
+ gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_OUTPUT, 0);
+ printf(".");
+ gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_OUTPUT, 1);
+ printf(".");
+ gpio_pin_test(cinfo, line,
+ GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW,
+ 0);
+ printf(".");
+ gpio_pin_test(cinfo, line,
+ GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW,
+ 1);
+ printf(".");
+ gpio_pin_test(cinfo, line, GPIOHANDLE_REQUEST_INPUT, 0);
+ printf(".");
+}
+
+/*
+ * ./gpio-mockup-chardev gpio_chip_name_prefix is_valid_gpio_chip
+ * Return 0 if successful or exit with EXIT_FAILURE if test failed.
+ * gpio_chip_name_prefix: The prefix of gpiochip you want to test. E.g.
+ * gpio-mockup
+ * is_valid_gpio_chip: Whether the gpio_chip is valid. 1 means valid,
+ * 0 means invalid which could not be found by
+ * list_gpiochip.
+ */
+int main(int argc, char *argv[])
+{
+ char *prefix;
+ int valid;
+ struct gpiochip_info *cinfo;
+ struct gpiochip_info *current;
+ int i;
+ int ret;
+
+ if (argc < 3) {
+ printf("Usage: %s prefix is_valid", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ prefix = argv[1];
+ valid = strcmp(argv[2], "true") == 0 ? 1 : 0;
+
+ printf("Test gpiochip %s: ", prefix);
+ cinfo = list_gpiochip(prefix, &ret);
+ if (!cinfo) {
+ if (!valid && ret == 0) {
+ printf("Invalid test successful\n");
+ ret = 0;
+ goto out;
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
+ } else if (cinfo && !valid) {
+ ret = -EINVAL;
+ goto out;
+ }
+ current = cinfo;
+ for (i = 0; i < ret; i++) {
+ gpio_pin_tests(current, 0);
+ gpio_pin_tests(current, current->lines - 1);
+ gpio_pin_tests(current, random() % current->lines);
+ current++;
+ }
+ ret = 0;
+ printf("successful\n");
+
+out:
+ if (ret)
+ fprintf(stderr, "gpio<%s> test failed\n", prefix);
+
+ if (cinfo)
+ free(cinfo);
+
+ if (ret)
+ exit(EXIT_FAILURE);
+
+ return ret;
+}
diff --git a/tools/testing/selftests/gpio/gpio-mockup-sysfs.sh b/tools/testing/selftests/gpio/gpio-mockup-sysfs.sh
new file mode 100755
index 000000000000..085d7a39899c
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio-mockup-sysfs.sh
@@ -0,0 +1,134 @@
+
+is_consistent()
+{
+ val=
+
+ active_low_sysfs=`cat $GPIO_SYSFS/gpio$nr/active_low`
+ val_sysfs=`cat $GPIO_SYSFS/gpio$nr/value`
+ dir_sysfs=`cat $GPIO_SYSFS/gpio$nr/direction`
+
+ gpio_this_debugfs=`cat $GPIO_DEBUGFS |grep "gpio-$nr" | sed "s/(.*)//g"`
+ dir_debugfs=`echo $gpio_this_debugfs | awk '{print $2}'`
+ val_debugfs=`echo $gpio_this_debugfs | awk '{print $3}'`
+ if [ $val_debugfs = "lo" ]; then
+ val=0
+ elif [ $val_debugfs = "hi" ]; then
+ val=1
+ fi
+
+ if [ $active_low_sysfs = "1" ]; then
+ if [ $val = "0" ]; then
+ val="1"
+ else
+ val="0"
+ fi
+ fi
+
+ if [ $val_sysfs = $val ] && [ $dir_sysfs = $dir_debugfs ]; then
+ echo -n "."
+ else
+ echo "test fail, exit"
+ die
+ fi
+}
+
+test_pin_logic()
+{
+ nr=$1
+ direction=$2
+ active_low=$3
+ value=$4
+
+ echo $direction > $GPIO_SYSFS/gpio$nr/direction
+ echo $active_low > $GPIO_SYSFS/gpio$nr/active_low
+ if [ $direction = "out" ]; then
+ echo $value > $GPIO_SYSFS/gpio$nr/value
+ fi
+ is_consistent $nr
+}
+
+test_one_pin()
+{
+ nr=$1
+
+ echo -n "test pin<$nr>"
+
+ echo $nr > $GPIO_SYSFS/export 2>/dev/null
+
+ if [ X$? != X0 ]; then
+ echo "test GPIO pin $nr failed"
+ die
+ fi
+
+ #"Checking if the sysfs is consistent with debugfs: "
+ is_consistent $nr
+
+ #"Checking the logic of active_low: "
+ test_pin_logic $nr out 1 1
+ test_pin_logic $nr out 1 0
+ test_pin_logic $nr out 0 1
+ test_pin_logic $nr out 0 0
+
+ #"Checking the logic of direction: "
+ test_pin_logic $nr in 1 1
+ test_pin_logic $nr out 1 0
+ test_pin_logic $nr low 0 1
+ test_pin_logic $nr high 0 0
+
+ echo $nr > $GPIO_SYSFS/unexport
+
+ echo "successful"
+}
+
+test_one_pin_fail()
+{
+ nr=$1
+
+ echo $nr > $GPIO_SYSFS/export 2>/dev/null
+
+ if [ X$? != X0 ]; then
+ echo "test invalid pin $nr successful"
+ else
+ echo "test invalid pin $nr failed"
+ echo $nr > $GPIO_SYSFS/unexport 2>/dev/null
+ die
+ fi
+}
+
+list_chip()
+{
+ echo `ls -d $GPIO_DRV_SYSFS/gpiochip* 2>/dev/null`
+}
+
+test_chip()
+{
+ chip=$1
+ name=`basename $chip`
+ base=`cat $chip/base`
+ ngpio=`cat $chip/ngpio`
+ printf "%-10s %-5s %-5s\n" $name $base $ngpio
+ if [ $ngpio = "0" ]; then
+ echo "number of gpio is zero is not allowed".
+ fi
+ test_one_pin $base
+ test_one_pin $(($base + $ngpio - 1))
+ test_one_pin $((( RANDOM % $ngpio ) + $base ))
+}
+
+test_chips_sysfs()
+{
+ gpiochip=`list_chip $module`
+ if [ X"$gpiochip" = X ]; then
+ if [ X"$valid" = Xfalse ]; then
+ echo "successful"
+ else
+ echo "fail"
+ die
+ fi
+ else
+ for chip in $gpiochip; do
+ test_chip $chip
+ done
+ fi
+}
+
diff --git a/tools/testing/selftests/gpio/gpio-mockup.sh b/tools/testing/selftests/gpio/gpio-mockup.sh
new file mode 100755
index 000000000000..b183439e058e
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio-mockup.sh
@@ -0,0 +1,201 @@
+#!/bin/bash
+
+#exit status
+#1: run as non-root user
+#2: sysfs/debugfs not mount
+#3: insert module fail when gpio-mockup is a module.
+#4: other reason.
+
+SYSFS=
+GPIO_SYSFS=
+GPIO_DRV_SYSFS=
+DEBUGFS=
+GPIO_DEBUGFS=
+dev_type=
+module=
+
+usage()
+{
+ echo "Usage:"
+ echo "$0 [-f] [-m name] [-t type]"
+ echo "-f: full test. It maybe conflict with existence gpio device."
+ echo "-m: module name, default name is gpio-mockup. It could also test"
+ echo " other gpio device."
+ echo "-t: interface type: chardev(char device) and sysfs(being"
+ echo " deprecated). The first one is default"
+ echo ""
+ echo "$0 -h"
+ echo "This usage"
+}
+
+prerequisite()
+{
+ msg="skip all tests:"
+ if [ $UID != 0 ]; then
+ echo $msg must be run as root >&2
+ exit 1
+ fi
+ SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
+ if [ ! -d "$SYSFS" ]; then
+ echo $msg sysfs is not mounted >&2
+ exit 2
+ fi
+ GPIO_SYSFS=`echo $SYSFS/class/gpio`
+ GPIO_DRV_SYSFS=`echo $SYSFS/devices/platform/$module/gpio`
+ DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+ if [ ! -d "$DEBUGFS" ]; then
+ echo $msg debugfs is not mounted >&2
+ exit 2
+ fi
+ GPIO_DEBUGFS=`echo $DEBUGFS/gpio`
+ source gpio-mockup-sysfs.sh
+}
+
+try_insert_module()
+{
+ if [ -d "$GPIO_DRV_SYSFS" ]; then
+ echo "$GPIO_DRV_SYSFS exist. Skip insert module"
+ else
+ modprobe -q $module $1
+ if [ X$? != X0 ]; then
+ echo $msg insmod $module failed >&2
+ exit 3
+ fi
+ fi
+}
+
+remove_module()
+{
+ modprobe -r -q $module
+}
+
+die()
+{
+ remove_module
+ exit 4
+}
+
+test_chips()
+{
+ if [ X$dev_type = Xsysfs ]; then
+ echo "WARNING: sysfs ABI of gpio is going to deprecated."
+ test_chips_sysfs $*
+ else
+ $BASE/gpio-mockup-chardev $*
+ fi
+}
+
+gpio_test()
+{
+ param=$1
+ valid=$2
+
+ if [ X"$param" = X ]; then
+ die
+ fi
+ try_insert_module "gpio_mockup_ranges=$param"
+ echo -n "GPIO $module test with ranges: <"
+ echo "$param>: "
+ printf "%-10s %s\n" $param
+ test_chips $module $valid
+ remove_module
+}
+
+BASE=`dirname $0`
+
+dev_type=
+TEMP=`getopt -o fhm:t: -n '$0' -- "$@"`
+
+if [ "$?" != "0" ]; then
+ echo "Parameter process failed, Terminating..." >&2
+ exit 1
+fi
+
+# Note the quotes around `$TEMP': they are essential!
+eval set -- "$TEMP"
+
+while true; do
+ case $1 in
+ -f)
+ full_test=true
+ shift
+ ;;
+ -h)
+ usage
+ exit
+ ;;
+ -m)
+ module=$2
+ shift 2
+ ;;
+ -t)
+ dev_type=$2
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "Internal error!"
+ exit 1
+ ;;
+ esac
+done
+
+if [ X"$module" = X ]; then
+ module="gpio-mockup"
+fi
+
+if [ X$dev_type != Xsysfs ]; then
+ dev_type="chardev"
+fi
+
+prerequisite
+
+echo "1. Test dynamic allocation of gpio successful means insert gpiochip and"
+echo " manipulate gpio pin successful"
+gpio_test "-1,32" true
+gpio_test "-1,32,-1,32" true
+gpio_test "-1,32,-1,32,-1,32" true
+if [ X$full_test = Xtrue ]; then
+ gpio_test "-1,32,32,64" true
+ gpio_test "-1,32,40,64,-1,5" true
+ gpio_test "-1,32,32,64,-1,32" true
+ gpio_test "0,32,32,64,-1,32,-1,32" true
+ gpio_test "-1,32,-1,32,0,32,32,64" true
+ echo "2. Do basic test: successful means insert gpiochip and"
+ echo " manipulate gpio pin successful"
+ gpio_test "0,32" true
+ gpio_test "0,32,32,64" true
+ gpio_test "0,32,40,64,64,96" true
+fi
+echo "3. Error test: successful means insert gpiochip failed"
+echo "3.1 Test number of gpio overflow"
+#Currently: The max number of gpio(1024) is defined in arm architecture.
+gpio_test "-1,32,-1,1024" false
+if [ X$full_test = Xtrue ]; then
+ echo "3.2 Test zero line of gpio"
+ gpio_test "0,0" false
+ echo "3.3 Test range overlap"
+ echo "3.3.1 Test corner case"
+ gpio_test "0,32,0,1" false
+ gpio_test "0,32,32,64,32,40" false
+ gpio_test "0,32,35,64,35,45" false
+ gpio_test "0,32,31,32" false
+ gpio_test "0,32,32,64,36,37" false
+ gpio_test "0,32,35,64,34,36" false
+ echo "3.3.2 Test inserting invalid second gpiochip"
+ gpio_test "0,32,30,35" false
+ gpio_test "0,32,1,5" false
+ gpio_test "10,32,9,14" false
+ gpio_test "10,32,30,35" false
+ echo "3.3.3 Test others"
+ gpio_test "0,32,40,56,39,45" false
+ gpio_test "0,32,40,56,30,33" false
+ gpio_test "0,32,40,56,30,41" false
+ gpio_test "0,32,40,56,20,21" false
+fi
+
+echo GPIO test PASS
+
diff --git a/tools/testing/selftests/nsfs/.gitignore b/tools/testing/selftests/nsfs/.gitignore
new file mode 100644
index 000000000000..2ab2c824ce86
--- /dev/null
+++ b/tools/testing/selftests/nsfs/.gitignore
@@ -0,0 +1,2 @@
+owner
+pidns
diff --git a/tools/testing/selftests/sigaltstack/.gitignore b/tools/testing/selftests/sigaltstack/.gitignore
new file mode 100644
index 000000000000..35897b0a3f44
--- /dev/null
+++ b/tools/testing/selftests/sigaltstack/.gitignore
@@ -0,0 +1 @@
+sas
diff --git a/tools/testing/selftests/sync/.gitignore b/tools/testing/selftests/sync/.gitignore
new file mode 100644
index 000000000000..f5091e7792f2
--- /dev/null
+++ b/tools/testing/selftests/sync/.gitignore
@@ -0,0 +1 @@
+sync_test
diff --git a/tools/testing/selftests/sync/Makefile b/tools/testing/selftests/sync/Makefile
new file mode 100644
index 000000000000..87ac400507c0
--- /dev/null
+++ b/tools/testing/selftests/sync/Makefile
@@ -0,0 +1,24 @@
+CFLAGS += -O2 -g -std=gnu89 -pthread -Wall -Wextra
+CFLAGS += -I../../../../usr/include/
+LDFLAGS += -pthread
+
+TEST_PROGS = sync_test
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+OBJS = sync_test.o sync.o
+
+TESTS += sync_alloc.o
+TESTS += sync_fence.o
+TESTS += sync_merge.o
+TESTS += sync_wait.o
+TESTS += sync_stress_parallelism.o
+TESTS += sync_stress_consumer.o
+TESTS += sync_stress_merge.o
+
+sync_test: $(OBJS) $(TESTS)
+
+clean:
+ $(RM) sync_test $(OBJS) $(TESTS)
diff --git a/tools/testing/selftests/sync/sw_sync.h b/tools/testing/selftests/sync/sw_sync.h
new file mode 100644
index 000000000000..e2cfc6bad83e
--- /dev/null
+++ b/tools/testing/selftests/sync/sw_sync.h
@@ -0,0 +1,46 @@
+/*
+ * sw_sync abstraction
+ *
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2013 Google, Inc
+ *
+ * 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.
+ */
+
+#ifndef SELFTESTS_SW_SYNC_H
+#define SELFTESTS_SW_SYNC_H
+
+/*
+ * sw_sync is mainly intended for testing and should not be compiled into
+ * production kernels
+ */
+
+int sw_sync_timeline_create(void);
+int sw_sync_timeline_is_valid(int fd);
+int sw_sync_timeline_inc(int fd, unsigned int count);
+void sw_sync_timeline_destroy(int fd);
+
+int sw_sync_fence_create(int fd, const char *name, unsigned int value);
+int sw_sync_fence_is_valid(int fd);
+void sw_sync_fence_destroy(int fd);
+
+#endif
diff --git a/tools/testing/selftests/sync/sync.c b/tools/testing/selftests/sync/sync.c
new file mode 100644
index 000000000000..f3d599f249b9
--- /dev/null
+++ b/tools/testing/selftests/sync/sync.c
@@ -0,0 +1,221 @@
+/*
+ * sync / sw_sync abstraction
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 <fcntl.h>
+#include <malloc.h>
+#include <poll.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "sync.h"
+#include "sw_sync.h"
+
+#include <linux/sync_file.h>
+
+
+/* SW_SYNC ioctls */
+struct sw_sync_create_fence_data {
+ __u32 value;
+ char name[32];
+ __s32 fence;
+};
+
+#define SW_SYNC_IOC_MAGIC 'W'
+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
+ struct sw_sync_create_fence_data)
+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
+
+
+int sync_wait(int fd, int timeout)
+{
+ struct pollfd fds;
+
+ fds.fd = fd;
+ fds.events = POLLIN | POLLERR;
+
+ return poll(&fds, 1, timeout);
+}
+
+int sync_merge(const char *name, int fd1, int fd2)
+{
+ struct sync_merge_data data = {};
+ int err;
+
+ data.fd2 = fd2;
+ strncpy(data.name, name, sizeof(data.name) - 1);
+ data.name[sizeof(data.name) - 1] = '\0';
+
+ err = ioctl(fd1, SYNC_IOC_MERGE, &data);
+ if (err < 0)
+ return err;
+
+ return data.fence;
+}
+
+static struct sync_file_info *sync_file_info(int fd)
+{
+ struct sync_file_info *info;
+ struct sync_fence_info *fence_info;
+ int err, num_fences;
+
+ info = calloc(1, sizeof(*info));
+ if (info == NULL)
+ return NULL;
+
+ err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
+ if (err < 0) {
+ free(info);
+ return NULL;
+ }
+
+ num_fences = info->num_fences;
+
+ if (num_fences) {
+ info->flags = 0;
+ info->num_fences = num_fences;
+
+ fence_info = calloc(num_fences, sizeof(*fence_info));
+ if (!fence_info) {
+ free(info);
+ return NULL;
+ }
+
+ info->sync_fence_info = (uint64_t)fence_info;
+
+ err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
+ if (err < 0) {
+ free(fence_info);
+ free(info);
+ return NULL;
+ }
+ }
+
+ return info;
+}
+
+static void sync_file_info_free(struct sync_file_info *info)
+{
+ free((void *)info->sync_fence_info);
+ free(info);
+}
+
+int sync_fence_size(int fd)
+{
+ int count;
+ struct sync_file_info *info = sync_file_info(fd);
+
+ if (!info)
+ return 0;
+
+ count = info->num_fences;
+
+ sync_file_info_free(info);
+
+ return count;
+}
+
+int sync_fence_count_with_status(int fd, int status)
+{
+ unsigned int i, count = 0;
+ struct sync_fence_info *fence_info = NULL;
+ struct sync_file_info *info = sync_file_info(fd);
+
+ if (!info)
+ return -1;
+
+ fence_info = (struct sync_fence_info *)info->sync_fence_info;
+ for (i = 0 ; i < info->num_fences ; i++) {
+ if (fence_info[i].status == status)
+ count++;
+ }
+
+ sync_file_info_free(info);
+
+ return count;
+}
+
+int sw_sync_timeline_create(void)
+{
+ return open("/sys/kernel/debug/sync/sw_sync", O_RDWR);
+}
+
+int sw_sync_timeline_inc(int fd, unsigned int count)
+{
+ __u32 arg = count;
+
+ return ioctl(fd, SW_SYNC_IOC_INC, &arg);
+}
+
+int sw_sync_timeline_is_valid(int fd)
+{
+ int status;
+
+ if (fd == -1)
+ return 0;
+
+ status = fcntl(fd, F_GETFD, 0);
+ return (status >= 0);
+}
+
+void sw_sync_timeline_destroy(int fd)
+{
+ if (sw_sync_timeline_is_valid(fd))
+ close(fd);
+}
+
+int sw_sync_fence_create(int fd, const char *name, unsigned int value)
+{
+ struct sw_sync_create_fence_data data = {};
+ int err;
+
+ data.value = value;
+ strncpy(data.name, name, sizeof(data.name) - 1);
+ data.name[sizeof(data.name) - 1] = '\0';
+
+ err = ioctl(fd, SW_SYNC_IOC_CREATE_FENCE, &data);
+ if (err < 0)
+ return err;
+
+ return data.fence;
+}
+
+int sw_sync_fence_is_valid(int fd)
+{
+ /* Same code! */
+ return sw_sync_timeline_is_valid(fd);
+}
+
+void sw_sync_fence_destroy(int fd)
+{
+ if (sw_sync_fence_is_valid(fd))
+ close(fd);
+}
diff --git a/tools/testing/selftests/sync/sync.h b/tools/testing/selftests/sync/sync.h
new file mode 100644
index 000000000000..fb7156148350
--- /dev/null
+++ b/tools/testing/selftests/sync/sync.h
@@ -0,0 +1,40 @@
+/*
+ * sync abstraction
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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.
+ */
+
+#ifndef SELFTESTS_SYNC_H
+#define SELFTESTS_SYNC_H
+
+#define FENCE_STATUS_ERROR (-1)
+#define FENCE_STATUS_ACTIVE (0)
+#define FENCE_STATUS_SIGNALED (1)
+
+int sync_wait(int fd, int timeout);
+int sync_merge(const char *name, int fd1, int fd2);
+int sync_fence_size(int fd);
+int sync_fence_count_with_status(int fd, int status);
+
+#endif
diff --git a/tools/testing/selftests/sync/sync_alloc.c b/tools/testing/selftests/sync/sync_alloc.c
new file mode 100644
index 000000000000..66a28afc05dc
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_alloc.c
@@ -0,0 +1,74 @@
+/*
+ * sync allocation tests
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int test_alloc_timeline(void)
+{
+ int timeline, valid;
+
+ timeline = sw_sync_timeline_create();
+ valid = sw_sync_timeline_is_valid(timeline);
+ ASSERT(valid, "Failure allocating timeline\n");
+
+ sw_sync_timeline_destroy(timeline);
+ return 0;
+}
+
+int test_alloc_fence(void)
+{
+ int timeline, fence, valid;
+
+ timeline = sw_sync_timeline_create();
+ valid = sw_sync_timeline_is_valid(timeline);
+ ASSERT(valid, "Failure allocating timeline\n");
+
+ fence = sw_sync_fence_create(timeline, "allocFence", 1);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure allocating fence\n");
+
+ sw_sync_fence_destroy(fence);
+ sw_sync_timeline_destroy(timeline);
+ return 0;
+}
+
+int test_alloc_fence_negative(void)
+{
+ int fence, timeline;
+
+ timeline = sw_sync_timeline_create();
+ ASSERT(timeline > 0, "Failure allocating timeline\n");
+
+ fence = sw_sync_fence_create(-1, "fence", 1);
+ ASSERT(fence < 0, "Success allocating negative fence\n");
+
+ sw_sync_fence_destroy(fence);
+ sw_sync_timeline_destroy(timeline);
+ return 0;
+}
diff --git a/tools/testing/selftests/sync/sync_fence.c b/tools/testing/selftests/sync/sync_fence.c
new file mode 100644
index 000000000000..13f175287da3
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_fence.c
@@ -0,0 +1,132 @@
+/*
+ * sync fence tests with one timeline
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int test_fence_one_timeline_wait(void)
+{
+ int fence, valid, ret;
+ int timeline = sw_sync_timeline_create();
+
+ valid = sw_sync_timeline_is_valid(timeline);
+ ASSERT(valid, "Failure allocating timeline\n");
+
+ fence = sw_sync_fence_create(timeline, "allocFence", 5);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure allocating fence\n");
+
+ /* Wait on fence until timeout */
+ ret = sync_wait(fence, 0);
+ ASSERT(ret == 0, "Failure waiting on fence until timeout\n");
+
+ /* Advance timeline from 0 -> 1 */
+ ret = sw_sync_timeline_inc(timeline, 1);
+ ASSERT(ret == 0, "Failure advancing timeline\n");
+
+ /* Wait on fence until timeout */
+ ret = sync_wait(fence, 0);
+ ASSERT(ret == 0, "Failure waiting on fence until timeout\n");
+
+ /* Signal the fence */
+ ret = sw_sync_timeline_inc(timeline, 4);
+ ASSERT(ret == 0, "Failure signaling the fence\n");
+
+ /* Wait successfully */
+ ret = sync_wait(fence, 0);
+ ASSERT(ret > 0, "Failure waiting on fence\n");
+
+ /* Go even further, and confirm wait still succeeds */
+ ret = sw_sync_timeline_inc(timeline, 10);
+ ASSERT(ret == 0, "Failure going further\n");
+ ret = sync_wait(fence, 0);
+ ASSERT(ret > 0, "Failure waiting ahead\n");
+
+ sw_sync_fence_destroy(fence);
+ sw_sync_timeline_destroy(timeline);
+
+ return 0;
+}
+
+int test_fence_one_timeline_merge(void)
+{
+ int a, b, c, d, valid;
+ int timeline = sw_sync_timeline_create();
+
+ /* create fence a,b,c and then merge them all into fence d */
+ a = sw_sync_fence_create(timeline, "allocFence", 1);
+ b = sw_sync_fence_create(timeline, "allocFence", 2);
+ c = sw_sync_fence_create(timeline, "allocFence", 3);
+
+ valid = sw_sync_fence_is_valid(a) &&
+ sw_sync_fence_is_valid(b) &&
+ sw_sync_fence_is_valid(c);
+ ASSERT(valid, "Failure allocating fences\n");
+
+ d = sync_merge("mergeFence", b, a);
+ d = sync_merge("mergeFence", c, d);
+ valid = sw_sync_fence_is_valid(d);
+ ASSERT(valid, "Failure merging fences\n");
+
+ /* confirm all fences have one active point (even d) */
+ ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
+ "a has too many active fences!\n");
+ ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
+ "b has too many active fences!\n");
+ ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
+ "c has too many active fences!\n");
+ ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_ACTIVE) == 1,
+ "d has too many active fences!\n");
+
+ /* confirm that d is not signaled until the max of a,b,c */
+ sw_sync_timeline_inc(timeline, 1);
+ ASSERT(sync_fence_count_with_status(a, FENCE_STATUS_SIGNALED) == 1,
+ "a did not signal!\n");
+ ASSERT(sync_fence_count_with_status(d, FENCE_STATUS_ACTIVE) == 1,
+ "d signaled too early!\n");
+
+ sw_sync_timeline_inc(timeline, 1);
+ ASSERT(sync_fence_count_with_status(b, FENCE_STATUS_SIGNALED) == 1,
+ "b did not signal!\n");
+ ASSERT(sync_fence_count_with_status(d, FENCE_STATUS_ACTIVE) == 1,
+ "d signaled too early!\n");
+
+ sw_sync_timeline_inc(timeline, 1);
+ ASSERT(sync_fence_count_with_status(c, FENCE_STATUS_SIGNALED) == 1,
+ "c did not signal!\n");
+ ASSERT(sync_fence_count_with_status(d, FENCE_STATUS_ACTIVE) == 0 &&
+ sync_fence_count_with_status(d, FENCE_STATUS_SIGNALED) == 1,
+ "d did not signal!\n");
+
+ sw_sync_fence_destroy(d);
+ sw_sync_fence_destroy(c);
+ sw_sync_fence_destroy(b);
+ sw_sync_fence_destroy(a);
+ sw_sync_timeline_destroy(timeline);
+ return 0;
+}
diff --git a/tools/testing/selftests/sync/sync_merge.c b/tools/testing/selftests/sync/sync_merge.c
new file mode 100644
index 000000000000..8914d43395c7
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_merge.c
@@ -0,0 +1,60 @@
+/*
+ * sync fence merge tests
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int test_fence_merge_same_fence(void)
+{
+ int fence, valid, merged;
+ int timeline = sw_sync_timeline_create();
+
+ valid = sw_sync_timeline_is_valid(timeline);
+ ASSERT(valid, "Failure allocating timeline\n");
+
+ fence = sw_sync_fence_create(timeline, "allocFence", 5);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure allocating fence\n");
+
+ merged = sync_merge("mergeFence", fence, fence);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure merging fence\n");
+
+ ASSERT(sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED) == 0,
+ "fence signaled too early!\n");
+
+ sw_sync_timeline_inc(timeline, 5);
+ ASSERT(sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED) == 1,
+ "fence did not signal!\n");
+
+ sw_sync_fence_destroy(merged);
+ sw_sync_fence_destroy(fence);
+ sw_sync_timeline_destroy(timeline);
+
+ return 0;
+}
diff --git a/tools/testing/selftests/sync/sync_stress_consumer.c b/tools/testing/selftests/sync/sync_stress_consumer.c
new file mode 100644
index 000000000000..d9eff8d524f7
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_stress_consumer.c
@@ -0,0 +1,185 @@
+/*
+ * sync stress test: producer/consumer
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 <pthread.h>
+
+#include "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+/* IMPORTANT NOTE: if you see this test failing on your system, it may be
+ * due to a shortage of file descriptors. Please ensure your system has
+ * a sensible limit for this test to finish correctly.
+ */
+
+/* Returns 1 on error, 0 on success */
+static int busy_wait_on_fence(int fence)
+{
+ int error, active;
+
+ do {
+ error = sync_fence_count_with_status(fence, FENCE_STATUS_ERROR);
+ ASSERT(error == 0, "Error occurred on fence\n");
+ active = sync_fence_count_with_status(fence,
+ FENCE_STATUS_ACTIVE);
+ } while (active);
+
+ return 0;
+}
+
+static struct {
+ int iterations;
+ int threads;
+ int counter;
+ int consumer_timeline;
+ int *producer_timelines;
+ pthread_mutex_t lock;
+} test_data_mpsc;
+
+static int mpsc_producer_thread(void *d)
+{
+ int id = (long)d;
+ int fence, valid, i;
+ int *producer_timelines = test_data_mpsc.producer_timelines;
+ int consumer_timeline = test_data_mpsc.consumer_timeline;
+ int iterations = test_data_mpsc.iterations;
+
+ for (i = 0; i < iterations; i++) {
+ fence = sw_sync_fence_create(consumer_timeline, "fence", i);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure creating fence\n");
+
+ /*
+ * Wait for the consumer to finish. Use alternate
+ * means of waiting on the fence
+ */
+
+ if ((iterations + id) % 8 != 0) {
+ ASSERT(sync_wait(fence, -1) > 0,
+ "Failure waiting on fence\n");
+ } else {
+ ASSERT(busy_wait_on_fence(fence) == 0,
+ "Failure waiting on fence\n");
+ }
+
+ /*
+ * Every producer increments the counter, the consumer
+ * checks and erases it
+ */
+ pthread_mutex_lock(&test_data_mpsc.lock);
+ test_data_mpsc.counter++;
+ pthread_mutex_unlock(&test_data_mpsc.lock);
+
+ ASSERT(sw_sync_timeline_inc(producer_timelines[id], 1) == 0,
+ "Error advancing producer timeline\n");
+
+ sw_sync_fence_destroy(fence);
+ }
+
+ return 0;
+}
+
+static int mpcs_consumer_thread(void)
+{
+ int fence, merged, tmp, valid, it, i;
+ int *producer_timelines = test_data_mpsc.producer_timelines;
+ int consumer_timeline = test_data_mpsc.consumer_timeline;
+ int iterations = test_data_mpsc.iterations;
+ int n = test_data_mpsc.threads;
+
+ for (it = 1; it <= iterations; it++) {
+ fence = sw_sync_fence_create(producer_timelines[0], "name", it);
+ for (i = 1; i < n; i++) {
+ tmp = sw_sync_fence_create(producer_timelines[i],
+ "name", it);
+ merged = sync_merge("name", tmp, fence);
+ sw_sync_fence_destroy(tmp);
+ sw_sync_fence_destroy(fence);
+ fence = merged;
+ }
+
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure merging fences\n");
+
+ /*
+ * Make sure we see an increment from every producer thread.
+ * Vary the means by which we wait.
+ */
+ if (iterations % 8 != 0) {
+ ASSERT(sync_wait(fence, -1) > 0,
+ "Producers did not increment as expected\n");
+ } else {
+ ASSERT(busy_wait_on_fence(fence) == 0,
+ "Producers did not increment as expected\n");
+ }
+
+ ASSERT(test_data_mpsc.counter == n * it,
+ "Counter value mismatch!\n");
+
+ /* Release the producer threads */
+ ASSERT(sw_sync_timeline_inc(consumer_timeline, 1) == 0,
+ "Failure releasing producer threads\n");
+
+ sw_sync_fence_destroy(fence);
+ }
+
+ return 0;
+}
+
+int test_consumer_stress_multi_producer_single_consumer(void)
+{
+ int iterations = 1 << 12;
+ int n = 5;
+ long i, ret;
+ int producer_timelines[n];
+ int consumer_timeline;
+ pthread_t threads[n];
+
+ consumer_timeline = sw_sync_timeline_create();
+ for (i = 0; i < n; i++)
+ producer_timelines[i] = sw_sync_timeline_create();
+
+ test_data_mpsc.producer_timelines = producer_timelines;
+ test_data_mpsc.consumer_timeline = consumer_timeline;
+ test_data_mpsc.iterations = iterations;
+ test_data_mpsc.threads = n;
+ test_data_mpsc.counter = 0;
+ pthread_mutex_init(&test_data_mpsc.lock, NULL);
+
+ for (i = 0; i < n; i++) {
+ pthread_create(&threads[i], NULL, (void * (*)(void *))
+ mpsc_producer_thread, (void *)i);
+ }
+
+ /* Consumer thread runs here */
+ ret = mpcs_consumer_thread();
+
+ for (i = 0; i < n; i++)
+ pthread_join(threads[i], NULL);
+
+ return ret;
+}
diff --git a/tools/testing/selftests/sync/sync_stress_merge.c b/tools/testing/selftests/sync/sync_stress_merge.c
new file mode 100644
index 000000000000..99e83ef45fbf
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_stress_merge.c
@@ -0,0 +1,115 @@
+/*
+ * sync stress test: merging
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int test_merge_stress_random_merge(void)
+{
+ int i, size, ret;
+ int timeline_count = 32;
+ int merge_count = 1024 * 32;
+ int timelines[timeline_count];
+ int fence_map[timeline_count];
+ int fence, tmpfence, merged, valid;
+ int timeline, timeline_offset, sync_point;
+
+ srand(time(NULL));
+
+ for (i = 0; i < timeline_count; i++)
+ timelines[i] = sw_sync_timeline_create();
+
+ fence = sw_sync_fence_create(timelines[0], "fence", 0);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure creating fence\n");
+
+ memset(fence_map, -1, sizeof(fence_map));
+ fence_map[0] = 0;
+
+ /*
+ * Randomly create sync_points out of a fixed set of timelines,
+ * and merge them together
+ */
+ for (i = 0; i < merge_count; i++) {
+ /* Generate sync_point. */
+ timeline_offset = rand() % timeline_count;
+ timeline = timelines[timeline_offset];
+ sync_point = rand();
+
+ /* Keep track of the latest sync_point in each timeline. */
+ if (fence_map[timeline_offset] == -1)
+ fence_map[timeline_offset] = sync_point;
+ else if (fence_map[timeline_offset] < sync_point)
+ fence_map[timeline_offset] = sync_point;
+
+ /* Merge */
+ tmpfence = sw_sync_fence_create(timeline, "fence", sync_point);
+ merged = sync_merge("merge", tmpfence, fence);
+ sw_sync_fence_destroy(tmpfence);
+ sw_sync_fence_destroy(fence);
+ fence = merged;
+
+ valid = sw_sync_fence_is_valid(merged);
+ ASSERT(valid, "Failure creating fence i\n");
+ }
+
+ size = 0;
+ for (i = 0; i < timeline_count; i++)
+ if (fence_map[i] != -1)
+ size++;
+
+ /* Confirm our map matches the fence. */
+ ASSERT(sync_fence_size(fence) == size,
+ "Quantity of elements not matching\n");
+
+ /* Trigger the merged fence */
+ for (i = 0; i < timeline_count; i++) {
+ if (fence_map[i] != -1) {
+ ret = sync_wait(fence, 0);
+ ASSERT(ret == 0,
+ "Failure waiting on fence until timeout\n");
+ /* Increment the timeline to the last sync_point */
+ sw_sync_timeline_inc(timelines[i], fence_map[i]);
+ }
+ }
+
+ /* Check that the fence is triggered. */
+ ret = sync_wait(fence, 0);
+ ASSERT(ret > 0, "Failure triggering fence\n");
+
+ sw_sync_fence_destroy(fence);
+
+ for (i = 0; i < timeline_count; i++)
+ sw_sync_timeline_destroy(timelines[i]);
+
+ return 0;
+}
diff --git a/tools/testing/selftests/sync/sync_stress_parallelism.c b/tools/testing/selftests/sync/sync_stress_parallelism.c
new file mode 100644
index 000000000000..e6c9be671dfc
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_stress_parallelism.c
@@ -0,0 +1,111 @@
+/*
+ * sync stress test: parallelism
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 <pthread.h>
+
+#include "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+static struct {
+ int iterations;
+ int timeline;
+ int counter;
+} test_data_two_threads;
+
+static int test_stress_two_threads_shared_timeline_thread(void *d)
+{
+ int thread_id = (long)d;
+ int timeline = test_data_two_threads.timeline;
+ int iterations = test_data_two_threads.iterations;
+ int fence, valid, ret, i;
+
+ for (i = 0; i < iterations; i++) {
+ fence = sw_sync_fence_create(timeline, "fence",
+ i * 2 + thread_id);
+ valid = sw_sync_fence_is_valid(fence);
+ ASSERT(valid, "Failure allocating fence\n");
+
+ /* Wait on the prior thread to complete */
+ ret = sync_wait(fence, -1);
+ ASSERT(ret > 0, "Problem occurred on prior thread\n");
+
+ /*
+ * Confirm the previous thread's writes are visible
+ * and then increment
+ */
+ ASSERT(test_data_two_threads.counter == i * 2 + thread_id,
+ "Counter got damaged!\n");
+ test_data_two_threads.counter++;
+
+ /* Kick off the other thread */
+ ret = sw_sync_timeline_inc(timeline, 1);
+ ASSERT(ret == 0, "Advancing timeline failed\n");
+
+ sw_sync_fence_destroy(fence);
+ }
+
+ return 0;
+}
+
+int test_stress_two_threads_shared_timeline(void)
+{
+ pthread_t a, b;
+ int valid;
+ int timeline = sw_sync_timeline_create();
+
+ valid = sw_sync_timeline_is_valid(timeline);
+ ASSERT(valid, "Failure allocating timeline\n");
+
+ test_data_two_threads.iterations = 1 << 16;
+ test_data_two_threads.counter = 0;
+ test_data_two_threads.timeline = timeline;
+
+ /*
+ * Use a single timeline to synchronize two threads
+ * hammmering on the same counter.
+ */
+
+ pthread_create(&a, NULL, (void *(*)(void *))
+ test_stress_two_threads_shared_timeline_thread,
+ (void *)0);
+ pthread_create(&b, NULL, (void *(*)(void *))
+ test_stress_two_threads_shared_timeline_thread,
+ (void *)1);
+
+ pthread_join(a, NULL);
+ pthread_join(b, NULL);
+
+ /* make sure the threads did not trample on one another */
+ ASSERT(test_data_two_threads.counter ==
+ test_data_two_threads.iterations * 2,
+ "Counter has unexpected value\n");
+
+ sw_sync_timeline_destroy(timeline);
+
+ return 0;
+}
diff --git a/tools/testing/selftests/sync/sync_test.c b/tools/testing/selftests/sync/sync_test.c
new file mode 100644
index 000000000000..9ea08d9f0b13
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_test.c
@@ -0,0 +1,79 @@
+/*
+ * sync test runner
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "synctest.h"
+
+static int run_test(int (*test)(void), char *name)
+{
+ int result;
+ pid_t childpid;
+
+ fflush(stdout);
+ childpid = fork();
+
+ if (childpid) {
+ waitpid(childpid, &result, 0);
+ if (WIFEXITED(result))
+ return WEXITSTATUS(result);
+ return 1;
+ }
+
+ printf("[RUN]\tExecuting %s\n", name);
+ exit(test());
+}
+
+int main(void)
+{
+ int err = 0;
+
+ printf("[RUN]\tTesting sync framework\n");
+
+ err += RUN_TEST(test_alloc_timeline);
+ err += RUN_TEST(test_alloc_fence);
+ err += RUN_TEST(test_alloc_fence_negative);
+
+ err += RUN_TEST(test_fence_one_timeline_wait);
+ err += RUN_TEST(test_fence_one_timeline_merge);
+ err += RUN_TEST(test_fence_merge_same_fence);
+ err += RUN_TEST(test_fence_multi_timeline_wait);
+ err += RUN_TEST(test_stress_two_threads_shared_timeline);
+ err += RUN_TEST(test_consumer_stress_multi_producer_single_consumer);
+ err += RUN_TEST(test_merge_stress_random_merge);
+
+ if (err)
+ printf("[FAIL]\tsync errors: %d\n", err);
+ else
+ printf("[OK]\tsync\n");
+
+ return !!err;
+}
diff --git a/tools/testing/selftests/sync/sync_wait.c b/tools/testing/selftests/sync/sync_wait.c
new file mode 100644
index 000000000000..d69b752f6550
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_wait.c
@@ -0,0 +1,91 @@
+/*
+ * sync fence wait tests
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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 "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int test_fence_multi_timeline_wait(void)
+{
+ int timelineA, timelineB, timelineC;
+ int fenceA, fenceB, fenceC, merged;
+ int valid, active, signaled, ret;
+
+ timelineA = sw_sync_timeline_create();
+ timelineB = sw_sync_timeline_create();
+ timelineC = sw_sync_timeline_create();
+
+ fenceA = sw_sync_fence_create(timelineA, "fenceA", 5);
+ fenceB = sw_sync_fence_create(timelineB, "fenceB", 5);
+ fenceC = sw_sync_fence_create(timelineC, "fenceC", 5);
+
+ merged = sync_merge("mergeFence", fenceB, fenceA);
+ merged = sync_merge("mergeFence", fenceC, merged);
+
+ valid = sw_sync_fence_is_valid(merged);
+ ASSERT(valid, "Failure merging fence from various timelines\n");
+
+ /* Confirm fence isn't signaled */
+ active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
+ ASSERT(active == 3, "Fence signaled too early!\n");
+
+ ret = sync_wait(merged, 0);
+ ASSERT(ret == 0,
+ "Failure waiting on fence until timeout\n");
+
+ ret = sw_sync_timeline_inc(timelineA, 5);
+ active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
+ signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
+ ASSERT(active == 2 && signaled == 1,
+ "Fence did not signal properly!\n");
+
+ ret = sw_sync_timeline_inc(timelineB, 5);
+ active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
+ signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
+ ASSERT(active == 1 && signaled == 2,
+ "Fence did not signal properly!\n");
+
+ ret = sw_sync_timeline_inc(timelineC, 5);
+ active = sync_fence_count_with_status(merged, FENCE_STATUS_ACTIVE);
+ signaled = sync_fence_count_with_status(merged, FENCE_STATUS_SIGNALED);
+ ASSERT(active == 0 && signaled == 3,
+ "Fence did not signal properly!\n");
+
+ /* confirm you can successfully wait */
+ ret = sync_wait(merged, 100);
+ ASSERT(ret > 0, "Failure waiting on signaled fence\n");
+
+ sw_sync_fence_destroy(merged);
+ sw_sync_fence_destroy(fenceC);
+ sw_sync_fence_destroy(fenceB);
+ sw_sync_fence_destroy(fenceA);
+ sw_sync_timeline_destroy(timelineC);
+ sw_sync_timeline_destroy(timelineB);
+ sw_sync_timeline_destroy(timelineA);
+
+ return 0;
+}
diff --git a/tools/testing/selftests/sync/synctest.h b/tools/testing/selftests/sync/synctest.h
new file mode 100644
index 000000000000..e7d1d57dba7a
--- /dev/null
+++ b/tools/testing/selftests/sync/synctest.h
@@ -0,0 +1,66 @@
+/*
+ * sync tests
+ * Copyright 2015-2016 Collabora Ltd.
+ *
+ * Based on the implementation from the Android Open Source Project,
+ *
+ * Copyright 2012 Google, Inc
+ *
+ * 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.
+ */
+
+#ifndef SELFTESTS_SYNCTEST_H
+#define SELFTESTS_SYNCTEST_H
+
+#include <stdio.h>
+
+#define ASSERT(cond, msg) do { \
+ if (!(cond)) { \
+ printf("[ERROR]\t%s", (msg)); \
+ return 1; \
+ } \
+} while (0)
+
+#define RUN_TEST(x) run_test((x), #x)
+
+/* Allocation tests */
+int test_alloc_timeline(void);
+int test_alloc_fence(void);
+int test_alloc_fence_negative(void);
+
+/* Fence tests with one timeline */
+int test_fence_one_timeline_wait(void);
+int test_fence_one_timeline_merge(void);
+
+/* Fence merge tests */
+int test_fence_merge_same_fence(void);
+
+/* Fence wait tests */
+int test_fence_multi_timeline_wait(void);
+
+/* Stress test - parallelism */
+int test_stress_two_threads_shared_timeline(void);
+
+/* Stress test - consumer */
+int test_consumer_stress_multi_producer_single_consumer(void);
+
+/* Stress test - merging */
+int test_merge_stress_random_merge(void);
+
+#endif
diff --git a/tools/testing/selftests/timers/.gitignore b/tools/testing/selftests/timers/.gitignore
index 68f3fc71ac44..cc986621f512 100644
--- a/tools/testing/selftests/timers/.gitignore
+++ b/tools/testing/selftests/timers/.gitignore
@@ -17,3 +17,4 @@ skew_consistency
threadtest
valid-adjtimex
adjtick
+set-tz